flush
[m6w6/ext-psi] / src / parser_proc.y
index 345ab226271fe0b12e419936298a764886a36bc1..0dc928f86d9d84106d0db790693a73fa6a3abc5c 100644 (file)
 %extra_argument {PSI_Parser *P}
 /* TOKEN is defined inside syntax_error */
 %syntax_error {
-       PSI_ParserSyntaxError(P, P->psi.file.fn, P->line, "Unexpected token '%s'", TOKEN->text);
+       if (TOKEN && TOKEN->type != PSI_T_EOF) {
+               PSI_ParserSyntaxError(P, P->psi.file.fn, P->line, "Unexpected token '%s'", TOKEN->text);
+       } else {
+               PSI_ParserSyntaxError(P, P->psi.file.fn, P->line, "Unexpected end of input");
+       }
 }
 
 %nonassoc NAME.
-%fallback NAME FREE SET LET RETURN LIB INT.
+%left PLUS MINUS.
+%left SLASH ASTERISK.
+%fallback NAME FREE SET LET RETURN LIB INT UNSIGNED.
 
 file ::= blocks.
 
 blocks ::= block.
 blocks ::= blocks block.
 
+block ::= EOF.
+
 block ::= LIB(T) QUOTED_STRING(libname) EOS. {
        if (P->psi.file.ln) {
                PSI_ParserSyntaxError(P, P->psi.file.ln, T->line, "Extra 'lib %s' statement has no effect", libname->text);
@@ -162,7 +170,7 @@ decl_vars(vars) ::= decl_vars(vars_) COMMA decl_var(var). {
 %type decl_arg {decl_arg*}
 %destructor decl_arg {free_decl_arg($$);}
 decl_arg(arg_) ::= const_decl_type(type) decl_var(var). {
-       arg_ = var->arg = init_decl_arg(type, var);
+       arg_ = init_decl_arg(type, var);
 }
 /* void pointers need a specific rule */
 decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). {
@@ -170,7 +178,6 @@ decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). {
                init_decl_type(T->type, T->text),
                init_decl_var(N->text, p, 0)
        );
-       arg_->var->arg = arg_;
        free(T);
        free(N);
 }
@@ -179,7 +186,6 @@ decl_arg(arg_) ::= CONST VOID(T) pointers(p) NAME(N). {
                init_decl_type(T->type, T->text),
                init_decl_var(N->text, p, 0)
        );
-       arg_->var->arg = arg_;
        free(T);
        free(N);
 }
@@ -227,6 +233,15 @@ decl_type(type_) ::= decl_type_token(T). {
        type_ = init_decl_type(T->type, T->text);
        free(T);
 }
+/* unsigned, urgh */
+decl_type(type_) ::= UNSIGNED NAME(T). {
+       type_ = init_decl_type(T->type, T->text);
+       type_->name = realloc(type_->name, T->size + sizeof("unsigned"));
+       memmove(type_->name + sizeof("unsigned"), type_->name, T->size);
+       memcpy(type_->name, "unsigned", sizeof("unsigned")-1);
+       type_->name[sizeof("unsigned")] = ' ';
+       type_->name[T->size + sizeof("unsigned")] = 0;
+}
 /* we have to support plain int here because we have it in our lexer rules */
 decl_type(type_) ::= INT(T). {
        type_ = init_decl_type(PSI_T_NAME, T->text);
@@ -260,7 +275,7 @@ impl_func(func) ::= FUNCTION NSNAME(NAME) impl_args(args) COLON impl_type(type).
        func = init_impl_func(NAME->text, args, type, 0);
        free(NAME);
 }
-impl_func(func) ::= FUNCTION REFERENCE NSNAME(NAME) impl_args(args) COLON impl_type(type). {
+impl_func(func) ::= FUNCTION AMPERSAND NSNAME(NAME) impl_args(args) COLON impl_type(type). {
        func = init_impl_func(NAME->text, args, type, 1);
        free(NAME);
 }
@@ -279,7 +294,7 @@ impl_var(var) ::= DOLLAR NAME(T). {
        var = init_impl_var(T->text, 0);
        free(T);
 }
-impl_var(var) ::= REFERENCE DOLLAR NAME(T). {
+impl_var(var) ::= AMPERSAND DOLLAR NAME(T). {
        var = init_impl_var(T->text, 1);
        free(T);
 }
@@ -345,17 +360,35 @@ let_stmt(let) ::= LET decl_var(var) EQUALS let_value(val) EOS. {
 
 %type let_value {let_value*}
 %destructor let_value {free_let_value($$);}
-let_value(val) ::= CALLOC(F) LPAREN NUMBER(N) COMMA decl_type(t) RPAREN. {
-       val = init_let_value(
-               init_let_func(F->type, F->text,
-                       init_let_calloc(
-                               atol(N->text), t
-                       )
-               ), NULL, 0
-       );
+let_value(val) ::= CALLOC(F) LPAREN let_calloc(alloc) RPAREN. {
+       val = init_let_value(init_let_func(F->type, F->text, alloc), NULL, 0);
        free(F);
-       free(N);
 }
+
+%type let_calloc {let_calloc*}
+%destructor let_calloc {free_let_calloc($$);}
+let_calloc(alloc) ::= num_exp(nmemb) COMMA num_exp(size). {
+       alloc = init_let_calloc(nmemb, size);
+}
+
+%token_class num_exp_token NUMBER NSNAME.
+%token_class num_exp_op_token PLUS MINUS ASTERISK SLASH.
+%type num_exp {num_exp*}
+%destructor num_exp {free_num_exp($$);}
+num_exp(exp) ::= num_exp_token(tok). {
+       exp = init_num_exp(tok->type, tok->text);
+       free(tok);
+}
+num_exp(exp) ::= decl_var(var). {
+       exp = init_num_exp(PSI_T_NAME, var);
+}
+num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). {
+       exp_->operator = operator_->type;
+       exp_->operand = operand_;
+       exp = exp_;
+       free(operator_);
+}
+
 let_value(val) ::= reference(r) let_func(func) LPAREN impl_var(var) RPAREN. {
        val = init_let_value(func, var, r);
 }
@@ -363,7 +396,7 @@ let_value(val) ::= reference(r) NULL. {
        val = init_let_value(NULL, NULL, r);
 }
 
-%token_class let_func_token ARRVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
+%token_class let_func_token OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
 %type let_func {let_func*}
 %destructor let_func {free_let_func($$);}
 let_func(func) ::= let_func_token(T). {
@@ -396,7 +429,7 @@ set_vals(vals) ::= set_vals(vals_) COMMA set_value(val). {
        vals = add_inner_set_value(vals_, val);
 }
 
-%token_class set_func_token TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL VOID.
+%token_class set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL VOID.
 %type set_func {set_func*}
 %destructor set_func {free_set_func($$);}
 set_func(func) ::= set_func_token(T). {
@@ -431,7 +464,7 @@ free_call(call) ::= NAME(F) LPAREN decl_vars(vars) RPAREN. {
        call = init_free_call(F->text, vars);
 }
 
-%token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY.
+%token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT.
 %type impl_type {impl_type*}
 %destructor impl_type {free_impl_type($$);}
 impl_type(type_) ::= impl_type_token(T). {
@@ -441,12 +474,12 @@ impl_type(type_) ::= impl_type_token(T). {
 
 %type reference {char}
 reference(r) ::= . {r = 0;}
-reference(r) ::= REFERENCE. {r = 1;}
+reference(r) ::= AMPERSAND. {r = 1;}
 
 %type indirection {unsigned}
 indirection(i) ::= . {i = 0;}
 indirection(i) ::= pointers(p). {i = p;}
 
 %type pointers {unsigned}
-pointers(p) ::= POINTER. {p = 1;}
-pointers(p) ::= pointers(P) POINTER. {p = P+1;}
+pointers(p) ::= ASTERISK. {p = 1;}
+pointers(p) ::= pointers(P) ASTERISK. {p = P+1;}