Пример #1
0
static struct ast_node*
continue_expr(void *opaque)
{
	struct ast_node_continue *continue_node;
	struct ast_node_stub *stub_node;
	struct scope_ctx helper;

	if (opaque == NULL) {
		error_msg("error: `continue' outside loop");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	helper = *(struct scope_ctx *)opaque;
	
	if (!helper.is_cycle) {
		error_msg("error: `continue' outside loop`");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	continue_node = ast_node_continue();
	
	return AST_NODE(continue_node);
}
Пример #2
0
static struct ast_node*
if_expr(void *opaque)
{
	struct ast_node_if *if_node;
	struct ast_node_stub *stub_node;
	struct ast_node *expr;
	struct ast_node *stmt_node;
	struct ast_node *_else;
	struct scope_ctx helper;

	if (!match(TOKEN_LPARENTH)) {
		error_msg("error: `(' expected after if");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	expr = or_expr();
	
	if (expr == NULL) {
		error_msg("error: expression expected after `('");
		sync_stream(); 
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	if (!match(TOKEN_RPARENTH)) {	
		error_msg("error: `)' expected after exprssion");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	if (opaque == NULL) {
		memset(&helper, 0, sizeof(helper));
		helper.is_cond++;
	} else {
		helper = *(struct scope_ctx *)opaque;
		helper.is_cond++;
	}	
		
	stmt_node = stmt(&helper);
		
	if (stmt_node == NULL) {
		error_msg("error: statment expected after `)'");
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}

	_else = NULL;

	if (match(TOKEN_ELSE))
		_else = stmt(&helper);
	
	if_node = ast_node_if(expr, stmt_node, _else);
		
	helper.is_cond--;
	
	return AST_NODE(if_node);
}
Пример #3
0
static struct ast_node*
break_expr(void *opaque)
{
	struct ast_node_stub *stub_node;
	struct ast_node_break *break_node;
	struct scope_ctx *helper;

	if (opaque == NULL) {
		error_msg("error: `break' outside loop");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);	
	}
	
	helper = (struct scope_ctx *)opaque;
	
	if (!helper->is_cycle) {
		error_msg("error: `break' outside loop");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	break_node = ast_node_break();
	
	return AST_NODE(break_node);
}
Пример #4
0
static struct ast_node*
process_scope(void *opaque)
{
	struct ast_node *stmt;
	struct ast_node_stub *stub_node;
	struct scope_ctx *helper;

	if (opaque == NULL) {
		error_msg("error: unexpected symbol");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}	
	
	helper = (struct scope_ctx *)opaque;

	if (!helper->is_cycle && !helper->is_cond) {
		error_msg("error: scope outside context");	
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
		
	stmt = stmts(opaque);	
		
	return stmt;
}
Пример #5
0
static struct ast_node*
while_expr(void *opaque)
{
	struct ast_node_stub *stub_node;
	struct ast_node_while *while_node;
	struct ast_node *expr;
	struct ast_node *_stmt;
	struct scope_ctx helper;

	if (!match(TOKEN_LPARENTH)) {		
		error_msg("errorr: `(' expected after while");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	expr = or_expr();
	
	if (expr == NULL) {
		error_msg("error: NULL expression in while()");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	if (!match(TOKEN_RPARENTH)) {
		error_msg("error: `)' expected after while(");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	if (opaque) {
		helper = *(struct scope_ctx *)opaque;
		helper.is_cycle++;
	} else {
		memset(&helper, 0, sizeof(helper));
		helper.is_cycle++;
	}
		
	_stmt = stmt(&helper);
	
	if (_stmt == NULL) {
		error_msg("error: statmet expected after while()");
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}

	while_node = ast_node_while(expr, _stmt);
	
	helper.is_cycle--;

	return AST_NODE(while_node);
}
Пример #6
0
static struct ast_node*
access_node(char *name)
{
	struct ast_node_stub *stub_node;
	struct ast_node_access *ac_node;
	struct ast_node *idx;
	struct symbol *sym;

	sym = symbol_table_lookup_all(name);
	
	if (sym == NULL) {
		error_msg("error: no such symbol");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	/* `[' */
	consume_token();
	
	ac_node = ast_node_access(sym->v_type, sym->name);

	do {
		idx = or_expr();
			
		if (idx == NULL) {	
			error_msg("error: empty index");
			sync_stream();
			goto ac_error;
		}
		
		ast_node_access_add(ac_node, idx);

		if (current_token != TOKEN_RBRACKET) {
			error_msg("error: missed `]'");	
			sync_stream();
			goto ac_error;
		}
		/* `]' */
		consume_token();

	} while (match(TOKEN_LBRACKET));

	return AST_NODE(ac_node);

ac_error:
	ast_node_unref(AST_NODE(ac_node));
	stub_node = ast_node_stub();

	return AST_NODE(stub_node);		
}
Пример #7
0
static GtkTreePath *
ast_get_path(GtkTreeModel *tree_model,
                  GtkTreeIter  *iter)
{
	GtkTreePath  *path;
	AstNode   *root = AST_NODE(tree_model);
	AstNode   *node = AST_NODE(iter->user_data);

	path = gtk_tree_path_new();
	while (node != root) {
		gtk_tree_path_prepend_index(path, node->index);
		node = node->parent;
	}
	return path;
}
Пример #8
0
struct ast_node*
process_function(void *opaque)
{
	char *name;
	struct ast_node_stub *stub_node;

	if (!match(TOKEN_ID)) {
		error_msg("error: function name expected after `function'");	
		sync_stream();
		goto exit;	
	}
	
	name = ustrdup(lex_prev.id);

	if (current_token != TOKEN_LPARENTH) {
		error_msg("error: `(' expected");
		sync_stream();
		goto exit;
	}
	
	process_args(name);
exit:	
	stub_node = ast_node_stub();

	return AST_NODE(stub_node);
}
Пример #9
0
struct ast_node*
token_id(char *name)
{
	struct ast_node *node;
	struct symbol *sym;

	switch (current_token) {
	case TOKEN_LPARENTH :
		node = function_call(name);
		break;
	case TOKEN_LBRACKET:
		node = access_node(name);
		break;
	default:		
		sym = symbol_table_lookup_all(name);
		
		if (sym == NULL) {
			sym = symbol_new(name, VALUE_TYPE_UNKNOWN);
			symbol_table_global_put_symbol(sym);
		}

		node = (struct ast_node *)ast_node_id(name);
		break;
	}

	return AST_NODE(node);	
}
Пример #10
0
static struct ast_node*
end_scope_expr(void *opaque)
{
	struct ast_node_stub *stub_node;
	struct ast_node_end_scope *scope_node;
	
	if (opaque == NULL) {
		error_msg("error: unexpected symbol");
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}

	scope_node = ast_node_end_scope();
	
	return AST_NODE(scope_node);
}
Пример #11
0
struct ast_node*
process_return_node(void *opaque)
{
	struct ast_node *ret_val;
	struct ast_node_return *_return;
	
	if (!opaque) {
		error_msg("error: return outside function");
		sync_stream();
		ret_val = (struct ast_node *)ast_node_stub();
		return AST_NODE(ret_val);
	}
	
	ret_val = sum_expr();
	
	_return = ast_node_return(ret_val);

	return AST_NODE(_return);
}
Пример #12
0
static struct ast_node*
rel_expr(void)
{
	struct ast_node *left;
	struct ast_node *right;
	struct ast_node_op *op_node;
	opcode_type_t opcode;

	left = sum_expr();

	if (left == NULL)
		return NULL;

	switch(current_token) {
	case TOKEN_EQ:
		consume_token();
		opcode = OPCODE_EQ;
		break;	
	case TOKEN_LT:
		consume_token();
		opcode = OPCODE_LT;
		break; 
	case TOKEN_GT:
		consume_token();
		opcode = OPCODE_GT;
		break;
	case TOKEN_LE:
		consume_token();
		opcode = OPCODE_LE;
		break;
	case TOKEN_GE:
		consume_token();
		opcode = OPCODE_GE;
		break;
	case TOKEN_NE:
		consume_token();
		opcode = OPCODE_NE;
		break;
	default:
		return left;
	}
	
	right = sum_expr();

	if (right == NULL) {
		error_msg("error: expression expected");
		right = (struct ast_node *)ast_node_stub();
		sync_stream();
	}
		
	op_node = ast_node_rel_op(opcode, left, right);
	
	return AST_NODE(op_node);		
}
Пример #13
0
struct ast_node*
process_local_declaration(void *opaque)
{
	struct scope_ctx helper;
	struct ast_node_stub *stub_node;
	struct symbol *var;

	if (opaque == NULL) {
		error_msg("error: `local' outside function");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);	
	}
	
	helper = *(struct scope_ctx *)opaque;
	
	if (!helper.is_func) {
		error_msg("error: `local' outside function");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	while (!match(TOKEN_EOL)) {
		if (match(TOKEN_ID)) {
			var = symbol_new(lex_prev.id, VALUE_TYPE_UNKNOWN);
			symbol_table_put_symbol(var);	
		}	
		
		if (current_token != TOKEN_EOL && !match(TOKEN_COMMA)) {
			error_msg("error: `,' expected after variable");
			sync_stream();
			stub_node = ast_node_stub();
			return AST_NODE(stub_node);
		}
	}

	stub_node = ast_node_stub();
	
	return AST_NODE(stub_node);
}
Пример #14
0
static struct ast_node*
unknown_expr(void *opaque)
{
	struct ast_node_stub *node;

	error_msg("error: unknown expression");

	sync_stream();	

	node = ast_node_stub();

	return AST_NODE(node);
}
Пример #15
0
static struct ast_node*
term(void)
{
	struct ast_node_const *_const;
	struct ast_node *node;

	if (match(TOKEN_ID)) {
		node = token_id(lex_prev.id);
		return node;
	} else if (match(TOKEN_DOUBLE)) {
		_const = ast_node_const(VALUE_TYPE_DIGIT, &lex_prev.real);
		return AST_NODE(_const);
	} else if (match(TOKEN_STRING)) {
		_const = ast_node_const(VALUE_TYPE_STRING, lex_prev.string);
		return AST_NODE(_const);
	} else if (match(TOKEN_LBRACKET)) {
		node = process_matrix();
		return node;
	}

	return NULL;
}
Пример #16
0
static void
ast_return_do_print(AstNode *self, FILE *out, int indention)
{
    assert(AST_IS_RETURN(self));
    assert(out);

    fprintf(out, "  return ");
    AstReturn *ret = (AstReturn *)self;
    if (ret->return_value != NULL)
    {
        ast_node_print(AST_NODE(ret->return_value), out, indention);
    }
    fprintf(out, "\n");
}
Пример #17
0
static gboolean
ast_get_iter(GtkTreeModel *tree_model,
                  GtkTreeIter  *iter,
                  GtkTreePath  *path)
{
	AstNode    *node;
	gint          *indices, depth;
	int i;

	node = AST_NODE(tree_model);
	indices = gtk_tree_path_get_indices(path);
	depth   = gtk_tree_path_get_depth(path);

	for (i = 0; i < depth; i++)
		node = ast_nth_child(node, indices[i]);

	return ast_set_iter(iter, node);
}
Пример #18
0
static struct ast_node*
other_expr(void *opaque)
{
	struct ast_node *node;
	struct ast_node_stub *stub_node;

	node = expr();	
		
	if (node == NULL) {
		if (current_token != TOKEN_EOL) {
			error_msg("error: unexpected symbol");
			sync_stream();
			stub_node = ast_node_stub();
			return AST_NODE(stub_node);
		}
	}
	
	return node;	
}
Пример #19
0
static struct ast_node*
expr(void)
{
	struct ast_node *lvalue;
	struct ast_node *rvalue;
	struct ast_node_assign *assign;

	lvalue = or_expr();
	
	if (current_token != TOKEN_EQUALITY)
		return lvalue;	
	/* `=' */
	consume_token();
	
	switch(lvalue->type) {
	case NODE_TYPE_ID:
	case NODE_TYPE_ACCESS:
		break;
	default:	
		error_msg("error: rvalue assignmet");
		sync_stream();
		return lvalue;
	}
	
	rvalue = or_expr();

	if (!rvalue) {
		error_msg("error: expression expected `='");
		sync_stream();
		rvalue = (struct ast_node *)ast_node_stub();
	}
	
	assign = ast_node_assign(lvalue, rvalue);

	return AST_NODE(assign);
}
Пример #20
0
static struct ast_node*
function_call(char *name)
{
	struct function *func_ctx;
	struct ast_node_func_call *func_call;
	struct ast_node_stub *stub_node;	
	struct ast_node *arg;
	int nargs = 0;

	func_ctx = function_table_lookup(name);

	consume_token();
	
	if (func_ctx == NULL) {
		error_msg("unknown function");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);	
	}

	func_call = ast_node_func_call(func_ctx->name);

	while (!match(TOKEN_RPARENTH)) {
		if (match(TOKEN_EOL)) {
			error_msg("EOL in function call");
			sync_stream();
			goto free;
			
		}
		
		arg = or_expr();

		if (arg == NULL) {
			error_msg("error: function argument expected");
			sync_stream();
			goto free;
		}
			
		nargs++;

		ast_node_func_call_add_arg(func_call, arg);
		
		if (current_token != TOKEN_RPARENTH && !match(TOKEN_COMMA)) {
			error_msg("error: missed comma");
			sync_stream();
			goto free;
		}				
	}
	
	if (func_ctx->nargs != nargs) {
		error_msg("error: unmatched arguments count");
		sync_stream();
		goto free;
	}

	return AST_NODE(func_call);	
free:
	ast_node_unref(AST_NODE(func_call));	
	stub_node = ast_node_stub();
	return	AST_NODE(stub_node);
}
Пример #21
0
static struct ast_node*
for_expr(void *opaque)
{
	struct ast_node_for *for_node;
	struct ast_node_stub *stub_node;
	struct ast_node *expr1;
	struct ast_node *expr2;
	struct ast_node *expr3;
	struct ast_node *_stmt;
	struct scope_ctx helper;

	if (!match(TOKEN_LPARENTH)) {
		error_msg("error: `(' expected after for");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	expr1 = expr();
	
	if (!match(TOKEN_SEMICOLON)) {
		error_msg("error: `;' expected after for(");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	expr2 = or_expr();

	if (!match(TOKEN_SEMICOLON)) {
		error_msg("error: `;' expected after for(;");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}	
	
	expr3 = expr();
		
	if (!match(TOKEN_RPARENTH)) {
		error_msg("error: `)' expected after for(;;");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	if (opaque) {
		helper = *(struct scope_ctx *)opaque;
		helper.is_cycle++;
	} else {	
		memset(&helper, 0, sizeof(helper));
		helper.is_cycle++;
	}

	_stmt = stmt(&helper);
	
	if (_stmt == NULL) {
		error_msg("error: stmt expected after for(;;)");
		sync_stream();
		stub_node = ast_node_stub();
		return AST_NODE(stub_node);
	}
	
	for_node = ast_node_for(expr1, expr2, expr3, _stmt);
	
	helper.is_cycle--;

	return AST_NODE(for_node);
}
Пример #22
0
static struct ast_node*
process_matrix(void)
{	
	struct ast_node_stub *stub_node;
	struct ast_node **elem;
	struct ast_node *node;	
	int row, col, len;
	int prev_col;
	int i;

	elem = NULL;
	node = NULL;

	row = col = 1;
	len = prev_col = 0;

	while (TRUE) {
		node = or_expr();

		if (node == NULL) {
			error_msg("expr expected");
			sync_stream();
			goto err;
		}		
		
		elem = urealloc(elem, ++len*sizeof(struct ast_node *));
		elem[len - 1] = node;

		switch(current_token) {
		case TOKEN_COMMA:
			consume_token();
			col++;
			continue;
		case TOKEN_SEMICOLON:
			consume_token();
			if (prev_col == 0)
				prev_col = col;
			else if (prev_col != col) {
				error_msg("incompatible column count");
				sync_stream();
				goto err;
			}
			col = 1;
			row++;
			continue;
		case TOKEN_RBRACKET:
			consume_token();
			break;
		default:
			error_msg("syntax error");
			sync_stream();
			goto err;
		} 
		break;							
	}

	if (row == 1 || col == 1)
		node = (struct ast_node *)ast_node_vector(elem, len);
	else
		node = (struct ast_node *) ast_node_matrix(elem, row, col);

	return node;

err:
	if (node != NULL)
		ast_node_unref(node);
	
	if (elem != NULL) 
		for (i = 0; i < len; i++)
			ast_node_unref(elem[i]);

	stub_node = ast_node_stub();

	return AST_NODE(stub_node);	
}