Example #1
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);
}
Example #2
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);
}
Example #3
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);
}
Example #4
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);
}
Example #5
0
File: syntax.c Project: loiso/scalc
static void
list_expr(void)
{	
	number res;
		
start:
	while (token.type == TOKEN_INTEGER ||token.type == TOKEN_LPARENTH || token.type == TOKEN_EOL || token.type == TOKEN_EOF) {

		if (token.type == TOKEN_EOL) {
			get_next_token();
			continue;
		}
		if (token.type == TOKEN_EOF) {
			return ;
		}		
		add_expr();

		if (err == SYN_ERR || err == MEM_ERR) {
			if (err == SYN_ERR)
				printf("syntax error\n");
			if (err == MEM_ERR)
				printf("memory error\n");
			sync_stream();
			sp.n = 0;
			err = 0;
			goto start;
		}
		pop_item(&sp, &res);
		print_value(res);
	}

	printf("syntax error\n");
	sync_stream();
	goto start;
}
Example #6
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);
}
Example #7
0
static void
process_args(char *name)
{
	struct function *func;
	struct symbol *arg;

	/*(*/
	consume_token();

	func = function_table_lookup(name);

	/* Delete an old function and make a new one */
	if (func != NULL) 
		function_table_delete_function(name);	

	func = function_new(name);
	
	while (!match(TOKEN_RPARENTH)) {
		if (match(TOKEN_EOL)) {
			error_msg("error: new line in function definition");
			return;	
		}
		
		if (!match(TOKEN_ID)) {
			error_msg("error: unexpected symbol in definition");
			sync_stream();
			ufree(func);
			return;
		}
	
		arg = symbol_new(lex_prev.id, VALUE_TYPE_UNKNOWN);
		
		function_add_arg(func, arg);
		
		if (current_token != TOKEN_RPARENTH && !match(TOKEN_COMMA)) {
			error_msg("error: comma expected");
			sync_stream();
			return;
		}			
	}

	switch(current_token) {
	case TOKEN_LBRACE:
		function_table_insert(func);
		process_function_body(name);
		break;
	default:
		error_msg("error: `{' expected");
		sync_stream();
		break;
	}	
}
Example #8
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);		
}
Example #9
0
static struct ast_node*
rest_or(struct ast_node *node)
{
	struct ast_node *ret_node;	
	struct ast_node *left;
	struct ast_node *right;

	ret_node = node;
	
	while (TRUE) {
		switch(current_token) {
		case TOKEN_OR :
			consume_token();

			left  = ret_node;
			right = and_expr();
			
			if (right == NULL) {
				error_msg("error: expression expected after ||");	
				right = (struct ast_node *)ast_node_stub();
				sync_stream();
			}
			ret_node = (struct ast_node *)ast_node_logic_op(OPCODE_OR, left, right);
			continue;
		default:
			goto exit_or;
		}
	}

exit_or:	
	return ret_node;
}
Example #10
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;
}
Example #11
0
static struct ast_node*
rest_and(struct ast_node *node)
{
	struct ast_node *ret_node;
	struct ast_node *left;
	struct ast_node *right;

	ret_node = node;
	
	while (TRUE) {
		switch (current_token) {
		case TOKEN_AND:
			consume_token();

			left  = ret_node;
			right = rel_expr();

			if (right == NULL) {
				error_msg("error: missed expression");
				right = (struct ast_node *)ast_node_stub();
				sync_stream();
			}	
			ret_node = (struct ast_node *)ast_node_logic_op(OPCODE_AND, left, right);
			continue;
		default:
			goto exit_and;
		}
	}

exit_and:
	return ret_node;
}
Example #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);		
}
Example #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);
}
Example #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);
}
Example #15
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);
}
Example #16
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;	
}
Example #17
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);
}
Example #18
0
static struct ast_node*
rest_exp(struct ast_node *node)
{
	struct ast_node *expr_node;
	struct ast_node *prev_node;
	struct ast_node *ret_node;
	char op;

	prev_node = node;

	while(TRUE) {
		switch(current_token) {
		case TOKEN_CARET:
			op = '^';
			break;
		default:
			goto exit_exp;			
		}

		consume_token();
		expr_node = term_expr();
	
		if (expr_node == NULL) {
			error_msg("error: syntax error");
			expr_node = (struct ast_node *)ast_node_stub();
			sync_stream();
			goto exit_exp;
		}
	
		prev_node = (struct ast_node *)ast_node_op(op, prev_node, expr_node);
	}
	
exit_exp:
	ret_node = prev_node;
	return ret_node;	
}
Example #19
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);	
}
Example #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);
}
Example #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);
}