Permalink
Browse files

added the call expression to the grammar

  • Loading branch information...
1 parent 9d7b343 commit dc369d60a850b1ee8b00a95e555dc00d3be7d360 @helino helino committed Mar 17, 2011
Showing with 62 additions and 11 deletions.
  1. +4 −4 specs/ast/call_spec.c
  2. +28 −0 specs/parser/expression_spec.c
  3. +6 −2 src/ast.c
  4. +1 −1 src/ast.h
  5. +23 −4 src/jurov.y
View
@@ -4,13 +4,13 @@
begin_example(mj_call, should_have_mj_call_as_type)
list *list;
- mj_ast_list *params;
+ ast *params;
ast *method;
ast *obj;
mj_call *c;
should_pass(new_list(&list))
- should_pass(new_mj_ast_list(list, (ast **) &params))
+ should_pass(new_mj_ast_list(list, &params))
should_pass(new_mj_identifier("bar", &obj))
should_pass(new_mj_identifier("foo", &method))
should_pass(new_mj_call(obj, method, params, (ast **) &c))
@@ -25,13 +25,13 @@ end_example
begin_example(mj_call, should_have_the_parameters_as_members)
list *list;
- mj_ast_list *params;
+ ast *params;
ast *method;
ast *obj;
mj_call *c;
should_pass(new_list(&list))
- should_pass(new_mj_ast_list(list, (ast **) &params))
+ should_pass(new_mj_ast_list(list, &params))
should_pass(new_mj_identifier("foo", &method))
should_pass(new_mj_identifier("bar", &obj))
should_pass(new_mj_call(obj, method, params, (ast **) &c))
@@ -294,6 +294,33 @@ begin_example(exp_parser, should_handle_less_than)
delete_parser(tree);
end_example
+begin_example(exp_parser, should_handle_call_exp)
+ ast *tree;
+ mj_call *call;
+ mj_identifier *obj;
+ mj_integer *first, *snd;
+ mj_identifier *method;
+ char *exp = "foo.double(1,2)";
+
+ should_pass(parse_expression(exp, &tree))
+ should_pass(get_expression(tree, (ast **) &call))
+ should_eq_int(MJ_CALL, call->type)
+ should_eq_int(MJ_IDENTIFIER, call->object->type)
+ obj = (mj_identifier *) call->object;
+ should_eq_str("foo", obj->name)
+ should_eq_int(MJ_IDENTIFIER, call->method->type)
+ method = (mj_identifier *) call->method;
+ should_eq_str("double", method->name);
+ should_eq_int(MJ_AST_LIST, call->parameters->type)
+ should_eq_int(2, call->parameters->list->size)
+ first = call->parameters->list->first->data;
+ should_eq_int(1, first->value)
+ snd = call->parameters->list->last->data;
+ should_eq_int(2, snd->value)
+
+ delete_parser(tree);
+end_example
+
begin_description(exp_parser)
add_example(should_handle_boolean_exp)
add_example(should_handle_integer_exp)
@@ -310,4 +337,5 @@ begin_description(exp_parser)
add_example(should_handle_subtraction)
add_example(should_handle_multiplication)
add_example(should_handle_less_than)
+ add_example(should_handle_call_exp)
end_description
View
@@ -132,19 +132,23 @@ int mj_ast_list_prepend(ast *list, ast *node)
return JRV_SUCCESS;
}
-int new_mj_call(ast *object, ast *method, mj_ast_list *parameters, ast **node)
+int new_mj_call(ast *object, ast *method, ast *parameters, ast **node)
{
mj_call *c;
if(!is_of_type(MJ_IDENTIFIER, method)) {
return invalid_type(node);
}
+ if(!is_of_type(MJ_AST_LIST, parameters)) {
+ return invalid_type(node);
+ }
+
c = jrv_malloc(sizeof(mj_call));
c->type = MJ_CALL;
c->object = object;
c->method = (mj_identifier *) method;
- c->parameters = parameters;
+ c->parameters = (mj_ast_list *) parameters;
*node = (ast *) c;
return JRV_SUCCESS;
}
View
@@ -280,7 +280,7 @@ typedef struct {
* of the function
* @return An integer describing the result of the function
*/
-int new_mj_call(ast *object, ast *method, mj_ast_list *parameters, ast **node);
+int new_mj_call(ast *object, ast *method, ast *parameters, ast **node);
/**
* Creates a new ast struct with type nodetype.THIS
View
@@ -34,7 +34,7 @@
if_statement while_statement assign_statement method_body
array_assignment_statement boolean number this relational_exp
additive_exp multiplicative_exp new_exp call_exp basic_exp
- unary_exp
+ unary_exp expressions more_expressions
%destructor { delete_ast($$); } program main_class main_method begin_class
function_body statements statement
@@ -47,7 +47,7 @@
array_assignment_statement boolean number
this relational_exp additive_exp
multiplicative_exp new_exp call_exp basic_exp
- unary_exp
+ unary_exp expressions more_expressions
%destructor { jrv_free(&$$); } ID
%%
start: program { *result = $1; }
@@ -206,7 +206,23 @@ print_statement: PRINT LPAREN expression RPAREN SEMICOLON
{ ast *node;
new_mj_print($3, &node);
$$ = node; }
-
+
+expressions: /* nothing, return the empty list */
+ { ast *node;
+ empty_mj_ast_list(&node);
+ $$ = node; }
+ | expression more_expressions
+ { mj_ast_list_prepend($2, $1);
+ $$ = $2; }
+
+more_expressions: /* nothing, return the empty list */
+ { ast *node;
+ empty_mj_ast_list(&node);
+ $$ = node; }
+ | COMMA expression more_expressions
+ { mj_ast_list_prepend($3, $2);
+ $$ = $3; }
+
expression: expression AND relational_exp
{ ast *node;
new_mj_binary_operation(MJ_AND, $1, $3, &node);
@@ -255,7 +271,10 @@ call_exp: call_exp DOT LENGTH
{ ast *node;
new_mj_unary_operation(MJ_ARRAY_LENGTH, $1, &node);
$$ = node; }
- /* add method call here */
+ | call_exp DOT identifier LPAREN expressions RPAREN
+ { ast *node;
+ new_mj_call($1, $3, $5, &node);
+ $$ = node; }
| call_exp LSQUARE basic_exp RSQUARE
{ ast *node;
new_mj_binary_operation(MJ_ARRAY_LOOKUP, $1, $3, &node);

0 comments on commit dc369d6

Please sign in to comment.