This patch makes the scanner recognize function names as distinct tokens
(and not just as identifiers). This gives the parser more information
and will also enable further changes.

The parser now only accepts functions with the correct number of
arguments. Before, mistakes like sin(a, b) or min(a) were silently
accepted.
---
 software/libfpvm/parser.y   |   36 +++++++++++++++++++++++++++++---
 software/libfpvm/scanner.re |   47 +++++++++++++++++++++++++++++++-----------
 2 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/software/libfpvm/parser.y b/software/libfpvm/parser.y
index 0cf2821..faf3ef6 100644
--- a/software/libfpvm/parser.y
+++ b/software/libfpvm/parser.y
@@ -44,7 +44,7 @@ node(N) ::= TOK_CONSTANT(C). {
        N->contents.constant = atof(C);
 }
 
-node(N) ::= TOK_IDENT(I). {
+node(N) ::= ident(I). {
        N = malloc(sizeof(struct ast_node));
        strncpy(N->label, I, sizeof(N->label));
        N->label[sizeof(N->label)-1] = 0;
@@ -111,7 +111,7 @@ node(N) ::= TOK_MINUS node(A). [TOK_NOT] {
        N->contents.branches.c = NULL;
 }
 
-node(N) ::= TOK_IDENT(I) TOK_LPAREN node(A) TOK_RPAREN. {
+node(N) ::= unary(I) TOK_LPAREN node(A) TOK_RPAREN. {
        N = malloc(sizeof(struct ast_node));
        strncpy(N->label, I, sizeof(N->label));
        N->label[sizeof(N->label)-1] = 0;
@@ -120,7 +120,7 @@ node(N) ::= TOK_IDENT(I) TOK_LPAREN node(A) TOK_RPAREN. {
        N->contents.branches.c = NULL;
 }
 
-node(N) ::= TOK_IDENT(I) TOK_LPAREN node(A) TOK_COMMA node(B) TOK_RPAREN. {
+node(N) ::= binary(I) TOK_LPAREN node(A) TOK_COMMA node(B) TOK_RPAREN. {
        N = malloc(sizeof(struct ast_node));
        strncpy(N->label, I, sizeof(N->label));
        N->label[sizeof(N->label)-1] = 0;
@@ -129,7 +129,8 @@ node(N) ::= TOK_IDENT(I) TOK_LPAREN node(A) TOK_COMMA 
node(B) TOK_RPAREN. {
        N->contents.branches.c = NULL;
 }
 
-node(N) ::= TOK_IDENT(I) TOK_LPAREN node(A) TOK_COMMA node(B) TOK_COMMA 
node(C) TOK_RPAREN. {
+node(N) ::= ternary(I) TOK_LPAREN node(A) TOK_COMMA node(B) TOK_COMMA node(C)
+    TOK_RPAREN. {
        N = malloc(sizeof(struct ast_node));
        strncpy(N->label, I, sizeof(N->label));
        N->label[sizeof(N->label)-1] = 0;
@@ -141,3 +142,30 @@ node(N) ::= TOK_IDENT(I) TOK_LPAREN node(A) TOK_COMMA 
node(B) TOK_COMMA node(C)
 node(N) ::= TOK_LPAREN node(A) TOK_RPAREN. {
        N = A;
 }
+
+ident(O) ::= TOK_IDENT(I).     { O = I; }
+ident(O) ::= unary(I).         { O = I; }
+ident(O) ::= binary(I).                { O = I; }
+ident(O) ::= ternary(I).       { O = I; }
+
+unary(O) ::= TOK_ABS(I).       { O = I; }
+unary(O) ::= TOK_COS(I).       { O = I; }
+unary(O) ::= TOK_F2I(I).       { O = I; }
+unary(O) ::= TOK_ICOS(I).      { O = I; }
+unary(O) ::= TOK_I2F(I).       { O = I; }
+unary(O) ::= TOK_INT(I).       { O = I; }
+unary(O) ::= TOK_INVSQRT(I).   { O = I; }
+unary(O) ::= TOK_ISIN(I).      { O = I; }
+unary(O) ::= TOK_QUAKE(I).     { O = I; }
+unary(O) ::= TOK_SIN(I).       { O = I; }
+unary(O) ::= TOK_SQR(I).       { O = I; }
+unary(O) ::= TOK_SQRT(I).      { O = I; }
+
+binary(O) ::= TOK_ABOVE(I).    { O = I; }
+binary(O) ::= TOK_BELOW(I).    { O = I; }
+binary(O) ::= TOK_EQUAL(I).    { O = I; }
+binary(O) ::= TOK_MAX(I).      { O = I; }
+binary(O) ::= TOK_MIN(I).      { O = I; }
+binary(O) ::= TOK_TSIGN(I).    { O = I; }
+
+ternary(O) ::= TOK_IF(I).      { O = I; }
diff --git a/software/libfpvm/scanner.re b/software/libfpvm/scanner.re
index cba81dc..2b1178f 100644
--- a/software/libfpvm/scanner.re
+++ b/software/libfpvm/scanner.re
@@ -56,19 +56,40 @@ int scan(struct scanner *s)
        s->old_cursor = s->cursor;
        
        /*!re2c
-               [\x20\r\t]                              { goto std; }
-               [0-9]+                                  { return TOK_CONSTANT; }
-               [0-9]* "." [0-9]*                       { return TOK_CONSTANT; }
-               [a-zA-Z_0-9]+                           { return TOK_IDENT; }
-               "+"                                     { return TOK_PLUS; }
-               "-"                                     { return TOK_MINUS; }
-               "*"                                     { return TOK_MULTIPLY; }
-               "/"                                     { return TOK_DIVIDE; }
-               "%"                                     { return TOK_PERCENT; }
-               "("                                     { return TOK_LPAREN; }
-               ")"                                     { return TOK_RPAREN; }
-               ","                                     { return TOK_COMMA; }
-               [\x00-\xff]                             { return TOK_ERROR; }
+               [\x20\r\t]              { goto std; }
+               [0-9]+                  { return TOK_CONSTANT; }
+               [0-9]* "." [0-9]*       { return TOK_CONSTANT; }
+
+               "above"                 { return TOK_ABOVE; }
+               "abs"                   { return TOK_ABS; }
+               "below"                 { return TOK_BELOW; }
+               "cos"                   { return TOK_COS; }
+               "equal"                 { return TOK_EQUAL; }
+               "f2i"                   { return TOK_F2I; }
+               "icos"                  { return TOK_ICOS; }
+               "i2f"                   { return TOK_I2F; }
+               "if"                    { return TOK_IF; }
+               "int"                   { return TOK_INT; }
+               "invsqrt"               { return TOK_INVSQRT; }
+               "isin"                  { return TOK_ISIN; }
+               "max"                   { return TOK_MAX; }
+               "min"                   { return TOK_MIN; }
+               "quake"                 { return TOK_QUAKE; }
+               "sin"                   { return TOK_SIN; }
+               "sqr"                   { return TOK_SQR; }
+               "sqrt"                  { return TOK_SQRT; }
+               "tsign"                 { return TOK_TSIGN; }
+
+               [a-zA-Z_0-9]+           { return TOK_IDENT; }
+               "+"                     { return TOK_PLUS; }
+               "-"                     { return TOK_MINUS; }
+               "*"                     { return TOK_MULTIPLY; }
+               "/"                     { return TOK_DIVIDE; }
+               "%"                     { return TOK_PERCENT; }
+               "("                     { return TOK_LPAREN; }
+               ")"                     { return TOK_RPAREN; }
+               ","                     { return TOK_COMMA; }
+               [\x00-\xff]             { return TOK_ERROR; }
        */
 }
 
-- 
1.7.1

_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode

Reply via email to