From 5ccebfdec189622b0c5b41eabb46fe67f8282443 Mon Sep 17 00:00:00 2001 From: "benjamin.franksen" <benjamin.franksen@helmholtz-berlin.de> Date: Wed, 2 Oct 2013 01:30:51 +0000 Subject: [PATCH] snc: allow indirect function calls This simply replaces 'ident ( args )' with 'expr ( args )' in the syntax. A few more changes in the code generator and we're done. --- src/snc/gen_ss_code.c | 16 ++++++++++------ src/snc/snl.lem | 38 ++++++++++++++++++-------------------- src/snc/types.h | 7 ++++--- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/snc/gen_ss_code.c b/src/snc/gen_ss_code.c index f30e4576..fd54cd25 100644 --- a/src/snc/gen_ss_code.c +++ b/src/snc/gen_ss_code.c @@ -445,9 +445,10 @@ static void gen_expr( gen_code("\"%s\"", ep->value); break; case E_FUNC: - if (gen_builtin_func(context, ep)) + if (ep->func_expr->type == E_VAR && gen_builtin_func(context, ep)) break; - gen_code("%s(", ep->value); + gen_expr(context, ep->func_expr, 0); + gen_code("("); foreach (cep, ep->func_args) { gen_expr(context, cep, 0); @@ -533,10 +534,13 @@ static int gen_builtin_const(Expr *ep) /* Generate builtin function call */ static int gen_builtin_func(int context, Expr *ep) { - char *func_name = ep->value; /* function name */ + char *func_name = ep->func_expr->value; Expr *ap; /* argument expr */ - struct func_symbol *sym = lookup_builtin_func(global_sym_table, func_name); + struct func_symbol *sym; + if (ep->func_expr->type != E_VAR) + return FALSE; + sym = lookup_builtin_func(global_sym_table, func_name); if (!sym) return FALSE; /* not a special function */ @@ -688,7 +692,7 @@ static void gen_pv_func( } #ifdef DEBUG - report("gen_pv_func: fun=%s, var=%s\n", ep->value, vp->name); + report("gen_pv_func: fun=%s, var=%s\n", func_name, vp->name); #endif gen_code(", "); if (vp->assign == M_NONE) @@ -767,7 +771,7 @@ static void gen_pv_func( /* Close the parameter list */ gen_code(")"); #ifdef DEBUG - report("gen_pv_func: done (fun=%s, var=%s)\n", ep->value, vp->name); + report("gen_pv_func: done (fun=%s, var=%s)\n", func_name, vp->name); #endif } diff --git a/src/snc/snl.lem b/src/snc/snl.lem index b5011b81..89b93887 100644 --- a/src/snc/snl.lem +++ b/src/snc/snl.lem @@ -44,7 +44,7 @@ in the file LICENSE that is included with this distribution. %token_type { Token } %default_type { Expr* } -/* Standard C operator table +/* Standard C operator table, highest precedence first. Primary Expression Operators () [] . -> expr++ expr-- left-to-right Unary Operators * & + - ! ~ ++expr --expr (typecast) sizeof() right-to-left Binary Operators * / % left-to-right @@ -62,8 +62,10 @@ in the file LICENSE that is included with this distribution. Comma , left-to-right */ -// PRE and POST are pseudo tokens, they only for the -// precedence declaration. +// PRE and POST are pseudo tokens used for precedence declaration. +// They are needed for operators that can appear in more than +// one position (and then have different precedences) because lemon +// allows only one precedence declaration for each token. // The comma operator is implemented as an extra production, // so we need no explicit precedence for it. @@ -80,10 +82,8 @@ in the file LICENSE that is included with this distribution. %left LSHIFT RSHIFT. %left ADD SUB. %left ASTERISK SLASH MOD. -%right CAST. -%right NOT INCR DECR PRE. -%left LBRACKET RBRACKET POINTER PERIOD POST. -// LPAREN RPAREN not listed as we do not support indirect calls. */ +%right NOT TILDE INCR DECR PRE. // omitted duplicates: ADD SUB ASTERISK AMPERSAND +%left LBRACKET LPAREN POINTER PERIOD POST. // omitted duplicates: INCR DECR program ::= PROGRAM NAME(n) @@ -400,19 +400,17 @@ expr(p) ::= FPCON(x). { p = expr(E_CONST, x); } expr(p) ::= string(x). { p = x; } expr(p) ::= variable(v). { p = expr(E_VAR, v); } -// Parenthesized -expr(p) ::= LPAREN(t) comma_expr(x) RPAREN. { p = expr(E_PAREN, t, x); } - // Primary Expression and Unary Postfix Operators -expr(p) ::= NAME(t) LPAREN args(xs) RPAREN. [POST] { p = expr(E_FUNC, t, xs); } -expr(p) ::= EXIT(t) LPAREN args(xs) RPAREN. [POST] { p = expr(E_FUNC, t, xs); } -expr(p) ::= SIZEOF(t) LPAREN expr(x) RPAREN. [POST] { p = expr(E_FUNC, t, x); } -expr(p) ::= SIZEOF(t) LPAREN type_expr(x) RPAREN.[POST] { p = expr(E_FUNC, t, x); } -expr(p) ::= expr(x) LBRACKET(t) expr(y) RBRACKET.[POST] { p = expr(E_SUBSCR, t, x, y); } -expr(p) ::= expr(x) PERIOD(t) member(y). [POST] { p = expr(E_SELECT, t, x, y); } -expr(p) ::= expr(x) POINTER(t) member(y). [POST] { p = expr(E_SELECT, t, x, y); } -expr(p) ::= expr(x) INCR(t). [POST] { p = expr(E_POST, t, x); } -expr(p) ::= expr(x) DECR(t). [POST] { p = expr(E_POST, t, x); } +expr(p) ::= LPAREN(t) comma_expr(x) RPAREN. { p = expr(E_PAREN, t, x); } +expr(p) ::= expr(x) LPAREN(t) args(y) RPAREN. { p = expr(E_FUNC, t, x, y); } +expr(p) ::= EXIT(n) LPAREN(t) args(y) RPAREN. { p = expr(E_FUNC, t, expr(E_VAR, n), y); } +expr(p) ::= SIZEOF(n) LPAREN(t) expr(y) RPAREN. { p = expr(E_FUNC, t, expr(E_VAR, n), y); } +expr(p) ::= SIZEOF(n) LPAREN(t) type_expr(y) RPAREN. { p = expr(E_FUNC, t, expr(E_VAR, n), y); } +expr(p) ::= expr(x) LBRACKET(t) expr(y) RBRACKET. { p = expr(E_SUBSCR, t, x, y); } +expr(p) ::= expr(x) PERIOD(t) member(y). { p = expr(E_SELECT, t, x, y); } +expr(p) ::= expr(x) POINTER(t) member(y). { p = expr(E_SELECT, t, x, y); } +expr(p) ::= expr(x) INCR(t). [POST] { p = expr(E_POST, t, x); } +expr(p) ::= expr(x) DECR(t). [POST] { p = expr(E_POST, t, x); } // Unary Prefix Operators expr(p) ::= ADD(t) expr(x). [PRE] { p = expr(E_PRE, t, x); } @@ -425,7 +423,7 @@ expr(p) ::= INCR(t) expr(x). [PRE] { p = expr(E_PRE, t, x); } expr(p) ::= DECR(t) expr(x). [PRE] { p = expr(E_PRE, t, x); } // Type Cast -expr(p) ::= LPAREN(t) type_expr(c) RPAREN expr(x). [CAST] { p = expr(E_CAST, t, c, x); } +expr(p) ::= LPAREN(t) type_expr(c) RPAREN expr(x). [PRE] { p = expr(E_CAST, t, c, x); } // Binary Operators, left-to-right expr(p) ::= expr(x) SUB(t) expr(y). { p = expr(E_BINOP, t, x, y); } diff --git a/src/snc/types.h b/src/snc/types.h index d940b470..2ee9027a 100644 --- a/src/snc/types.h +++ b/src/snc/types.h @@ -286,7 +286,7 @@ enum expr_type /* description [child expressions...] */ E_BINOP, /* binary operator [left,right] */ E_CAST, /* type cast [operand] */ E_CONST, /* numeric (inkl. character) constant [] */ - E_FUNC, /* function call [args] */ + E_FUNC, /* function call [expr,args] */ E_INIT, /* array or struct initializer [elems] */ E_MEMBER, /* struct or union member [] */ E_PAREN, /* parenthesis around an expression [expr] */ @@ -332,7 +332,8 @@ STATIC_ASSERT(NUM_EXPR_TYPES <= 8*sizeof(TypeMask)); #define for_cond children[1] #define for_iter children[2] #define for_stmt children[3] -#define func_args children[0] +#define func_expr children[0] +#define func_args children[1] #define if_cond children[0] #define if_then children[1] #define if_else children[2] @@ -405,7 +406,7 @@ expr_type_info[] { "E_BINOP", 2 }, { "E_CAST", 2 }, { "E_CONST", 0 }, - { "E_FUNC", 1 }, + { "E_FUNC", 2 }, { "E_INIT", 1 }, { "E_MEMBER", 0 }, { "E_PAREN", 1 }, -- GitLab