Beispiel #1
0
void test_equals_string() {
	String str = copy_string("abc");
	assert(equals_string(str, "abc"));
	assert(equals_string(NULL, NULL));
	assert(!equals_string(str, NULL));
	assert(!equals_string(NULL, str));
}
Beispiel #2
0
static statement *parse_func_call(linked_list *tokens) {
	linked_list *accumulator = ll_new();
	linked_iter iterator = ll_iter_head(tokens);
	statement *call = new(call);
	call->type = FUNC_CALL;
	call->data = ((parse_token*)ll_iter_next(&iterator))->data;
	call->children = ll_new();
	int paren_level = 0;
	ll_iter_next(&iterator); //Discard opening parenthesis
	for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) {
		if(paren_level == 0 && (equals_string(current->data, ",") || equals_string(current->data, ")"))) {
			statement *parameter = parse_simple_expression(accumulator);
			if(parameter != NULL)
				ll_add_last(call->children, parameter);
			ll_clear(accumulator);
		} else {
			ll_add_last(accumulator, current);
		}
		if(equals_string(current->data, "("))
			paren_level += 1;
		else if(equals_string(current->data, ")"))
			paren_level -= 1;
	}
	statement *parameter = parse_simple_expression(accumulator);
	if(parameter != NULL)
		ll_add_last(call->children, parameter);
	ll_destroy(accumulator);
	return call;
}
Beispiel #3
0
void parse_string_as_argument_list(caValue* str, List* output)
{
    // Read the tokens as a space-seperated list of strings.
    // TODO is to be more smart about word boundaries: spaces inside
    // quotes or parentheses shouldn't break apart items.

    TokenStream tokens;
    tokens.reset(as_cstring(str));
    
    Value itemInProgress;
    set_string(&itemInProgress, "");

    while (!tokens.finished()) {

        if (tokens.nextIs(tok_Whitespace)) {
            if (!equals_string(&itemInProgress, "")) {
                copy(&itemInProgress, list_append(output));
                set_string(&itemInProgress, "");
            }

        } else {
            string_append(&itemInProgress, tokens.nextStr().c_str());
        }

        tokens.consume();
    }

    if (!equals_string(&itemInProgress, "")) {
        copy(&itemInProgress, list_append(output));
        set_string(&itemInProgress, "");
    }
}
Beispiel #4
0
String eval_sys(Mapping *m, Statement *source, Queue *repQueue) {
	String prepare = copy_string(m->sys->prepare);
	String eval = copy_string(m->sys->eval);
	Mapping *mapping = NULL;

	String* array = NULL;
	String* arraySource = NULL;
	String* arrayTarget = NULL;

	String prepareSource;
	String prepareTarget;
	String sourceFuncMacro;
	String sourceMacro;
	String targetFuncMacro;
	String targetMacro;

	if (!equals_string(prepare, "NIL")) {
		mapping = alloc_mapping();
		mapping->sys = NULL;
		if (strcmp(m->sys->name, DEF_MACRO) == 0) {
			mapping->isMacro = TRUE;
		} else {
			mapping->isMacro = FALSE;
		}

		array = split_string_once(prepare, '>');
		prepareSource = array[0];
		prepareTarget = array[1];

		arraySource = split_string_once(prepareSource, ',');
		sourceFuncMacro = trim_string(arraySource[0]);
		sourceMacro = trim_string(arraySource[1]);

		mapping->source = parse_macro(repQueue, sourceMacro);
		mapping->sourceFunc = parse_macro(repQueue, sourceFuncMacro);
		mapping->sourceStatement = parse(mapping->source);
		mapping->starter = to_dfa(mapping->sourceStatement);

		arrayTarget = split_string_once(prepareTarget, ',');
		targetFuncMacro = trim_string(arrayTarget[0]);
		targetMacro = trim_string(arrayTarget[1]);

		mapping->target = parse_macro(repQueue, targetMacro);
		mapping->targetFunc = parse_macro(repQueue, targetFuncMacro);
		mapping->targetStatement = parse(mapping->target);

		//enqueue(get_mappings(), mapping);
		add_mapping_to_trie(mapping);
	}

	if (!equals_string(eval, "NIL")) {
		return parse_macro(repQueue, eval);
	} else {
		return "";
	}
}
Beispiel #5
0
static import_declaration *parse_import(parse_source *source) {
    parse_token current = get_mandatory_token(source);
    import_declaration *imp = new(imp);
    imp->name = current.data;
    current = get_mandatory_token(source);
    if(!equals_string(current.data, ";")) {
        semantic_error("Expected semicolon after import statement", current.origin);
    }
    return imp;
}
Beispiel #6
0
static enum_declaration *parse_enum(parse_source *source) {
	enum_declaration *dec = new(dec);
	parse_token current = get_mandatory_token(source);
	dec->name = current.data;
	dec->options = ll_new();
	while(!equals_string(get_mandatory_token(source).data, "}")) {
		statement *expr = new(expr);
		current = get_mandatory_token(source);
		expr->data = current.data;
		ll_add_last(dec->options, expr);
	}
	return dec;
}
Beispiel #7
0
int main(int argc, char **argv) {
	Scheme *sc = alloc_scheme();
	Statement *st = NULL;
	String scheme = NULL;

	if (!scheme_init(sc)) {
		fprintf(stderr, "Initialize scheme environment error!\n");
		return 1;
	}

	if (!funny_init()) {
		fprintf(stderr, "Initialize funny environment error!\n");
		return 1;
	}

	printf("Welcome to FUNNY programming world. Type {exit} to exit.\n");

	while (TRUE) {
		printf("> ");
		st = read_statement(stdin);

		if (empty_statement(st)) {
			printf("can't parse the statement.\n");
			continue;
		}

		wait_to_exit(st);

		scheme = match(st);

		if (equals_string(scheme, ""))
			continue;

//#ifdef DEBUG
		printf("TARGET: %s\n", scheme);
//#endif

		Cell* result = eval(sc, scheme);
		printf("%s\n", cell2str(sc, result));
	}

	return 0;
}
Beispiel #8
0
void do_admin_command(caValue* input, caValue* reply)
{
    // Identify the command
    int first_space = string_find_char(input, 0, ' ');
    if (first_space == -1)
        first_space = string_length(input);

    Value command;
    string_slice(input, 0, first_space, &command);

    set_null(reply);

    if (equals_string(&command, "add_lib_path")) {
        //List args;
        //parse_tokens_as_argument_list(&tokens, &args);

    } else if (equals_string(&command, "file")) {

        List args;
        parse_string_as_argument_list(input, &args);
        do_file_command(&args, reply);

    } else if (equals_string(&command, "echo")) {

        List args;
        parse_string_as_argument_list(input, &args);
        do_echo(&args, reply);

    } else if (equals_string(&command, "write_block")) {

        int nextSpace = string_find_char(input, first_space+1, ' ');
        if (nextSpace == -1) {
            set_string(reply, "Syntax error, not enough arguments");
            return;
        }
        
        Value blockName;
        string_slice(input, first_space+1, nextSpace, &blockName);

        Value contents;
        string_slice(input, nextSpace+1, -1, &contents);

        do_write_block(&blockName, &contents, reply);

    } else if (equals_string(&command, "update_file")) {

        int nextSpace = string_find_char(input, first_space+1, ' ');
        if (nextSpace == -1) {
            set_string(reply, "Syntax error, not enough arguments");
            return;
        }
        
        Value filename;
        string_slice(input, first_space+1, nextSpace, &filename);

        Value contents;
        string_slice(input, nextSpace+1, -1, &contents);

        do_update_file(&filename, &contents, reply);

    } else if (equals_string(&command, "source_repro")) {
        List args;
        parse_string_as_argument_list(input, &args);
        Block block;
        load_script(&block, as_cstring(args[1]));
        std::cout << get_block_source_text(&block);
    } else if (equals_string(&command, "dump_stats")) {

        perf_stats_dump();
        std::cout << ":done" << std::endl;

    } else {

        set_string(reply, "Unrecognized command: ");
        string_append(reply, &command);
    }
}
Beispiel #9
0
static statement *parse_simple_expression(linked_list *tokens) {
	while(equals_string(((parse_token*)ll_get_first(tokens))->data, "(") && equals_string(((parse_token*)ll_get_last(tokens))->data, ")")) {
		ll_remove_first(tokens);
		ll_remove_last(tokens);
	}
	int size = ll_size(tokens);
	switch(size) {
	case 0:
		return NULL;
	case 1:
		return parse_single_token(tokens);
	default: {
		if(size == 2) {
			parse_token *token = ll_get_first(tokens);
			bool isStack;
	        if((isStack = equals_string(token->data, "new")) || equals_string(token->data, "newref")) {
	            statement *expression = new(expression);
	            expression->children = ll_new();
	            expression->type = isStack ? STACK_INIT : HEAP_INIT;
	            linked_list *name = ll_duplicate(tokens);
	            ll_remove_first(name);
	            ll_add_first(expression->children, parse_simple_expression(name));
	            return expression;
	        }
		}
		int paren_level = 1;
		linked_iter iterator = ll_iter_head(tokens);
		bool is_index = true, is_call = true;
		ll_iter_next(&iterator);
		parse_token *second = ll_iter_next(&iterator);
		if(equals_string(second->data, "(")) {
			is_index = false;
		} else if(equals_string(second->data, "[")) {
			is_call = false;
		} else {
			is_index = is_call = false;
		}
		while((is_index || is_call) && ll_iter_has_next(&iterator)) {
			parse_token *token = ll_iter_next(&iterator);
			if(equals_string(token->data, "(") || equals_string(token->data, "[")) {
				paren_level += 1;
			} else if(paren_level == 0) {
				is_index = false;
				is_call = false;
			} else if(equals_string(token->data, ")") || equals_string(token->data, "]")) {
				paren_level -= 1;
			}
		}
		if(is_index) {
			return parse_array_index(tokens);
		} else if(is_call) {
			return parse_func_call(tokens);
		}
		linked_list *operator = get_node();
		linked_iter level = ll_iter_head(operator);
		while(ll_iter_has_next(&level)) {
			int paren_level = 0;
			linked_list *currentLevel = ll_iter_next(&level);
			linked_iter iterator = ll_iter_head(tokens);
			for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) {
				char currentChar = current->data.data[0];
				if(currentChar == '(') {
					paren_level += 1;
				} else if(currentChar == ')') {
					paren_level -= 1;
				}
				if(paren_level != 0) continue;
				linked_iter innerMost = ll_iter_head(currentLevel);
				while(ll_iter_has_next(&innerMost)) {
					operator_node *currentOperator = ll_iter_next(&innerMost);
					if(equals_string(current->data, currentOperator->data)) {
						if(!is_unary_operator(new_slice(currentOperator->data))) {
							linked_list *op1 = ll_duplicate(tokens);
							while(ll_get_last(op1) != current)
								ll_remove_last(op1);
							ll_remove_last(op1);
							linked_list *op2 = tokens;
							while(ll_get_first(op2) != current)
								ll_remove_first(op2);
							ll_remove_first(op2);
							statement *expression = new(expression);
							expression->data = new_slice("");
							expression->children = ll_new();
							expression->type = currentOperator->operatorType;
							statement *op1_exp = parse_simple_expression(op1);
							statement *op2_exp = parse_simple_expression(op2);
							ll_add_last(expression->children, op1_exp);
							ll_add_last(expression->children, op2_exp);
							return expression;
						} else {
							statement *expression = new(expression);
							expression->data = new_slice(currentOperator->data);
							expression->type = currentOperator->operatorType;
							linked_list *rest = ll_duplicate(tokens);
							ll_remove_first(rest);
							expression->children = ll_new();
							ll_add_first(expression->children, parse_simple_expression(rest));
							return expression;
						}
					}
				}
			}
		}
		return NULL;
		}
	}
}
Beispiel #10
0
static statement *get_expression(parse_source *source, int *indent) {
	parse_token token = get_mandatory_token(source);
	if(equals_string(token.data, "{")) {
		statement *expression = new(expression);
		expression->type = BLOCK;
		expression->children = ll_new();
		expression->data = new_slice("");
		int finished = *indent;
		*indent += 1;
		while(*indent != finished) {
			statement *state = get_expression(source, indent);
			if(state != NULL)
				ll_add_last(expression->children, state);
		}
		return expression;
	} else if(equals_string(token.data, "}")) {
		*indent -= 1;
		return NULL;
	} else if(equals_string(token.data, "if") || equals_string(token.data, "while") || equals_string(token.data, "for")) {
		statement *expression = new(expression);
		if(equals_string(token.data, "if"))
			expression->type = IF;
		else if(equals_string(token.data, "while"))
			expression->type = WHILE;
		else if(equals_string(token.data, "for"))
			expression->type = FOR;
		expression->children = ll_new();
		expression->data = new_slice("");
		ll_add_last(expression->children, get_expression(source, indent)); //Add the header
        if(expression->type == FOR) {
            ll_add_last(expression->children, get_expression(source, indent)); //Add the header
            ll_add_last(expression->children, get_expression(source, indent)); //Add the header
        }
		ll_add_last(expression->children, get_expression(source, indent)); //Add the body
		if(expression->type == IF) {
			parse_token next = peek_mandatory_token(source);
			if(equals_string(next.data, "else")) {
				get_mandatory_token(source);
				statement *elseState = new(elseState);
				elseState->type = ELSE;
				elseState->children = ll_new();
				elseState->data = new_slice("");
				ll_add_last(expression->children, elseState);
				ll_add_first(elseState->children, get_expression(source, indent));
			}
		}
		return expression;
	} else if(equals_string(token.data, "break") || equals_string(token.data, "continue")) {
		statement *expression = new(expression);
		expression->type = equals_string(token.data, "break") ? BREAK : CONTINUE;
		expression->data = new_slice("");
		expression->children = NULL;
		parse_token next = get_mandatory_token(source);
		if(!equals_string(next.data, ";"))
			semantic_error("Expected a semicolon after a break or continue", next.origin);
		return expression;
	} else if(equals_string(token.data, "return")) {
		statement *expression = new(expression);
		expression->type = RETURN;
		expression->data = new_slice("");
		expression->children = ll_new();
		ll_add_last(expression->children, get_expression(source, indent));
		return expression;
	} else {
		linked_list *accumulator = ll_new();
		parse_token next = token;
		while(true) {
			parse_token *allocated = new(allocated);
			*allocated = token;
			ll_add_last(accumulator, allocated);
			next = peek_mandatory_token(source);
			if(equals_string(next.data, "{") || equals_string(next.data, "}"))
				break;
			if(equals_string(next.data, ";")) {
				get_mandatory_token(source);
				break;
			}
			token = get_mandatory_token(source);
		}
		statement *expression = parse_simple_expression(accumulator);
		ll_delete_all(accumulator);
		return expression;
	}
}