Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: m-labs/flickernoise
base: 01c5e10
...
head fork: m-labs/flickernoise
compare: 35aef26
  • 6 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
Commits on Dec 30, 2011
Werner Almesberger wpwrak parser.y: added section titles to improve readability b933013
Werner Almesberger wpwrak compiler: recognize ==, <, and > as aliases for equal, above, below cdc9ffe
Werner Almesberger wpwrak compiler: rename op_not to op_negate
Furthermore, show the unary minus as  (- x)  instead of  (! x)  in
debugging/test output.

Note that this requires an update for the corresponding change in
milkymist.git
62da9eb
Werner Almesberger wpwrak compiler: add unary ! operator (basic support only) 369310a
Werner Almesberger wpwrak compiler: if(!a, b, c) now gets converted to if(a, c, b)
This removes the unary not code generation wouldn't be able to handle
from the AST.
cb733ac
Werner Almesberger wpwrak compiler: added relational operators !=, <=, and >=
They are implemented with unary nots, so we can only generate code when
they are used in a condition.
35aef26
2  src/compiler/compiler.c
View
@@ -554,7 +554,7 @@ static const char *assign_default(struct parser_comm *comm,
case op_constant:
v = node->contents.constant;
break;
- case op_not:
+ case op_negate:
if(node->contents.branches.a->op == op_constant) {
v = -node->contents.branches.a->contents.constant;
break;
98 src/compiler/parser.y
View
@@ -142,6 +142,12 @@
static struct ast_node *conditional(struct ast_node *a,
struct ast_node *b, struct ast_node *c)
{
+ if(a->op == op_not) {
+ struct ast_node *next = a->contents.branches.a;
+
+ parse_free_one(a);
+ return node_op(op_if, "if", next, c, b);
+ }
if(a->op != op_constant)
return node_op(op_if, "if", a, b, c);
if(a->contents.constant) {
@@ -175,6 +181,8 @@
%type expr {struct ast_node *}
%type cond_expr {struct ast_node *}
+%type equal_expr {struct ast_node *}
+%type rel_expr {struct ast_node *}
%type add_expr {struct ast_node *}
%type mult_expr {struct ast_node *}
%type unary_expr {struct ast_node *}
@@ -182,6 +190,8 @@
%destructor expr { free($$); }
%destructor cond_expr { free($$); }
+%destructor equal_expr { free($$); }
+%destructor rel_expr { free($$); }
%destructor add_expr { free($$); }
%destructor multexpr { free($$); }
%destructor unary_expr { free($$); }
@@ -202,6 +212,10 @@ start ::= TOK_START_ASSIGN sections. {
state->success = 1;
}
+
+/* ----- Sections and assignments ------------------------------------------ */
+
+
sections ::= assignments.
sections ::= assignments per_frame_label assignments.
sections ::= assignments per_frame_label assignments per_vertex_label
@@ -278,18 +292,63 @@ opt_semi ::= opt_semi TOK_SEMI.
opt_semi ::= .
+
+/* ----- Operators --------------------------------------------------------- */
+
+
expr(N) ::= cond_expr(A). {
N = A;
}
-cond_expr(N) ::= add_expr(A). {
+cond_expr(N) ::= equal_expr(A). {
N = A;
}
-cond_expr(N) ::= add_expr(A) TOK_QUESTION expr(B) TOK_COLON cond_expr(C). {
+cond_expr(N) ::= equal_expr(A) TOK_QUESTION expr(B) TOK_COLON cond_expr(C). {
N = conditional(A, B, C);
}
+equal_expr(N) ::= rel_expr(A). {
+ N = A;
+}
+
+equal_expr(N) ::= equal_expr(A) TOK_EQ rel_expr(B). {
+ FOLD_BINARY(N, op_equal, "equal", A, B, a == b);
+}
+
+equal_expr(N) ::= equal_expr(A) TOK_NE rel_expr(B). {
+ struct ast_node *tmp;
+
+ FOLD_BINARY(tmp, op_equal, "equal", A, B, a == b);
+ FOLD_UNARY(N, op_not, "!", tmp, !a);
+}
+
+rel_expr(N) ::= add_expr(A). {
+ N = A;
+}
+
+rel_expr(N) ::= rel_expr(A) TOK_LT add_expr(B). {
+ FOLD_BINARY(N, op_below, "below", A, B, a < b);
+}
+
+rel_expr(N) ::= rel_expr(A) TOK_GT add_expr(B). {
+ FOLD_BINARY(N, op_above, "above", A, B, a > b);
+}
+
+rel_expr(N) ::= rel_expr(A) TOK_LE add_expr(B). {
+ struct ast_node *tmp;
+
+ FOLD_BINARY(tmp, op_above, "above", A, B, a > b);
+ FOLD_UNARY(N, op_not, "!", tmp, !a);
+}
+
+rel_expr(N) ::= rel_expr(A) TOK_GE add_expr(B). {
+ struct ast_node *tmp;
+
+ FOLD_BINARY(tmp, op_below, "below", A, B, a < b);
+ FOLD_UNARY(N, op_not, "!", tmp, !a);
+}
+
add_expr(N) ::= mult_expr(A). {
N = A;
}
@@ -323,9 +382,17 @@ unary_expr(N) ::= primary_expr(A). {
}
unary_expr(N) ::= TOK_MINUS unary_expr(A). {
- FOLD_UNARY(N, op_not, "!", A, -a);
+ FOLD_UNARY(N, op_negate, "-", A, -a);
}
+unary_expr(N) ::= TOK_NOT unary_expr(A). {
+ FOLD_UNARY(N, op_not, "!", A, !a);
+}
+
+
+/* ----- Unary functions --------------------------------------------------- */
+
+
primary_expr(N) ::= unary_misc(I) TOK_LPAREN expr(A) TOK_RPAREN. {
N = node(I->token, I->label, A, NULL, NULL);
free(I);
@@ -336,6 +403,10 @@ primary_expr(N) ::= TOK_SQR(I) TOK_LPAREN expr(A) TOK_RPAREN. {
free(I);
}
+
+/* ----- Binary functions -------------------------------------------------- */
+
+
primary_expr(N) ::= binary_misc(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
TOK_RPAREN. {
N = node(I->token, I->label, A, B, NULL);
@@ -372,12 +443,20 @@ primary_expr(N) ::= TOK_MIN(I) TOK_LPAREN expr(A) TOK_COMMA expr(B)
free(I);
}
+
+/* ----- Trinary functions ------------------------------------------------- */
+
+
primary_expr(N) ::= TOK_IF(I) TOK_LPAREN expr(A) TOK_COMMA expr(B) TOK_COMMA
expr(C) TOK_RPAREN. {
N = conditional(A, B, C);
free(I);
}
+
+/* ----- Primary expressions ----------------------------------------------- */
+
+
primary_expr(N) ::= TOK_LPAREN expr(A) TOK_RPAREN. {
N = A;
}
@@ -392,6 +471,19 @@ primary_expr(N) ::= ident(I). {
free(I);
}
+
+/* ----- Identifiers ------------------------------------------------------- */
+
+/*
+ * Function names are not reserved words. If not followed by an opening
+ * parenthesis, they become regular identifiers.
+ *
+ * {u,bi,ter}nary are identifiers that have an individual rule, e.g., because
+ * they have function-specific code for constant folding. {u,bi,ter}nary_misc
+ * are identifiers the parser treats as generic functions, without knowing
+ * anything about their semantics.
+ */
+
ident(O) ::= TOK_IDENT(I). { O = I; }
ident(O) ::= unary(I). { O = I; }
ident(O) ::= unary_misc(I). { O = I; }
5 src/compiler/parser_helper.c
View
@@ -143,6 +143,11 @@ const char *parse(const char *expr, int start_token, struct parser_comm *comm)
return error;
}
+void parse_free_one(struct ast_node *node)
+{
+ free(node);
+}
+
void parse_free(struct ast_node *node)
{
if(node == NULL) return;
7 src/compiler/parser_helper.h
View
@@ -21,6 +21,12 @@
#include <fpvm/ast.h>
#include <fpvm/fpvm.h>
+
+/* virtual operation - for use inside the parser only */
+enum {
+ op_not = op_vops+1,
+};
+
struct compiler_sc;
struct parser_comm {
@@ -40,6 +46,7 @@ struct parser_comm {
};
const char *parse(const char *expr, int start_token, struct parser_comm *comm);
+void parse_free_one(struct ast_node *node);
void parse_free(struct ast_node *node);
#endif /* __PARSER_HELPER_H */
7 src/compiler/ptest/ptest.c
View
@@ -110,8 +110,8 @@ static void dump_ast(const struct ast_node *ast)
case op_quake:
op("quake", ast);
break;
- case op_not:
- op("!", ast);
+ case op_negate:
+ op("-", ast);
break;
case op_sqr:
op("sqr", ast);
@@ -131,6 +131,9 @@ static void dump_ast(const struct ast_node *ast)
case op_int:
op("int", ast);
break;
+ case op_not:
+ op("!", ast);
+ break;
default:
abort();
}
7 src/compiler/scanner.re
View
@@ -138,6 +138,13 @@ int scan(struct scanner *s)
<N>"," { return TOK_COMMA; }
<N>"?" { return TOK_QUESTION; }
<N>":" { return TOK_COLON; }
+ <N>"!" { return TOK_NOT; }
+ <N>"==" { return TOK_EQ; }
+ <N>"!=" { return TOK_NE; }
+ <N>"<" { return TOK_LT; }
+ <N>">" { return TOK_GT; }
+ <N>"<=" { return TOK_LE; }
+ <N>">=" { return TOK_GE; }
<N,FNAME1>"=" { if (YYGETCONDITION() == yycFNAME1)
YYSETCONDITION(yycFNAME2);
103 src/compiler/test/not
View
@@ -0,0 +1,103 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "not: !a" << EOF
+x = !a
+EOF
+expect <<EOF
+x = (! a)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest_fail "not: !a (try to generate code)" -c << EOF
+per_frame: wave_a = !a
+EOF
+expect <<EOF
+FPVM, line 2: Operation not supported: ! near 'EOF'
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !0" << EOF
+x = !0
+EOF
+expect <<EOF
+x = 1
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !1" << EOF
+x = !1
+EOF
+expect <<EOF
+x = 0
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !a*b" << EOF
+x = !a*b
+EOF
+expect <<EOF
+x = (* (! a) b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: -!a" << EOF
+x = -!a
+EOF
+expect <<EOF
+x = (- (! a))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !-b" << EOF
+x = !-b
+EOF
+expect <<EOF
+x = (! (- b))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: if (!a, b, c)" << EOF
+x = if (!a, b, c)
+EOF
+expect <<EOF
+x = (if a c b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !a ? b : c" << EOF
+x = !a ? b : c
+EOF
+expect <<EOF
+x = (if a c b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !0 ? b : c" << EOF
+x = !0 ? b : c
+EOF
+expect <<EOF
+x = b
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "not: !1 ? b : c" << EOF
+x = !1 ? b : c
+EOF
+expect <<EOF
+x = c
+EOF
+
+###############################################################################
16 src/compiler/test/prec
View
@@ -61,7 +61,7 @@ ptest "precedence: x = -a*b" <<EOF
x = -a*b
EOF
expect <<EOF
-x = (* (! a) b)
+x = (* (- a) b)
EOF
#------------------------------------------------------------------------------
@@ -70,7 +70,7 @@ ptest "precedence: x = a/b" <<EOF
x = -a/b
EOF
expect <<EOF
-x = (/ (! a) b)
+x = (/ (- a) b)
EOF
#------------------------------------------------------------------------------
@@ -79,7 +79,7 @@ ptest "precedence: x = a%b" <<EOF
x = -a%b
EOF
expect <<EOF
-x = (% (! a) b)
+x = (% (- a) b)
EOF
#------------------------------------------------------------------------------
@@ -88,7 +88,7 @@ ptest "precedence: x = -sin(a)" <<EOF
x = -sin(a)
EOF
expect <<EOF
-x = (! (sin a))
+x = (- (sin a))
EOF
#------------------------------------------------------------------------------
@@ -97,7 +97,7 @@ ptest "precedence: x = -max(a, b)" <<EOF
x = -max(a, b)
EOF
expect <<EOF
-x = (! (max a b))
+x = (- (max a b))
EOF
#------------------------------------------------------------------------------
@@ -106,7 +106,7 @@ ptest "precedence: x = -if(a, b, c)" <<EOF
x = -if(a, b, c)
EOF
expect <<EOF
-x = (! (if a b c))
+x = (- (if a b c))
EOF
#------------------------------------------------------------------------------
@@ -115,7 +115,7 @@ ptest "precedence: x = -(a+b)" <<EOF
x = -(a+b)
EOF
expect <<EOF
-x = (! (+ a b))
+x = (- (+ a b))
EOF
#------------------------------------------------------------------------------
@@ -124,7 +124,7 @@ ptest "precedence: x = a--b" <<EOF
x = a--b
EOF
expect <<EOF
-x = (- a (! b))
+x = (- a (- b))
EOF
###############################################################################
214 src/compiler/test/relop
View
@@ -0,0 +1,214 @@
+#!/bin/sh
+. ./Common
+
+###############################################################################
+
+ptest "relop: a == b" << EOF
+x = a == b
+EOF
+expect <<EOF
+x = (equal a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a < b" << EOF
+x = a < b
+EOF
+expect <<EOF
+x = (below a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a > b" << EOF
+x = a > b
+EOF
+expect <<EOF
+x = (above a b)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: fold ==" << EOF
+x = 1 == 2
+y = 2 == 2
+z = 3 == 2
+EOF
+expect <<EOF
+x = 0
+y = 1
+z = 0
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: fold <" << EOF
+x = 1 < 2
+y = 2 < 2
+z = 3 < 2
+EOF
+expect <<EOF
+x = 1
+y = 0
+z = 0
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: fold >" << EOF
+x = 1 > 2
+y = 2 > 2
+z = 3 > 2
+EOF
+expect <<EOF
+x = 0
+y = 0
+z = 1
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a == b ? c : d" << EOF
+x = a == b ? c : d
+EOF
+expect <<EOF
+x = (if (equal a b) c d)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a ? b : c == d" << EOF
+x = a ? b : c == d
+EOF
+expect <<EOF
+x = (if a b (equal c d))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a < b == c > d" << EOF
+x = a < b == c > d
+EOF
+expect <<EOF
+x = (equal (below a b) (above c d))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a+b < c-d" << EOF
+x = a+b < c-d
+EOF
+expect <<EOF
+x = (below (+ a b) (- c d))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a-b > c+d" << EOF
+x = a-b > c+d
+EOF
+expect <<EOF
+x = (above (- a b) (+ c d))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a != b" << EOF
+x = a != b
+EOF
+expect <<EOF
+x = (! (equal a b))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a <= b" << EOF
+x = a <= b
+EOF
+expect <<EOF
+x = (! (above a b))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a >= b" << EOF
+x = a >= b
+EOF
+expect <<EOF
+x = (! (below a b))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a < b != c >= d" << EOF
+x = a < b != c >= d
+EOF
+expect <<EOF
+x = (! (equal (below a b) (! (below c d))))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a+b <= c-d" << EOF
+x = a+b <= c-d
+EOF
+expect <<EOF
+x = (! (above (+ a b) (- c d)))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a-b >= c+d" << EOF
+x = a-b >= c+d
+EOF
+expect <<EOF
+x = (! (below (- a b) (+ c d)))
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a != b ? c : d" << EOF
+x = a != b ? c : d
+EOF
+expect <<EOF
+x = (if (equal a b) d c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a <= b ? c : d" << EOF
+x = a <= b ? c : d
+EOF
+expect <<EOF
+x = (if (above a b) d c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: a >= b ? c : d" << EOF
+x = a >= b ? c : d
+EOF
+expect <<EOF
+x = (if (below a b) d c)
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: 1 != 2 ? c : d" << EOF
+x = 1 != 2 ? c : d
+EOF
+expect <<EOF
+x = c
+EOF
+
+#------------------------------------------------------------------------------
+
+ptest "relop: 2 != 2 ? c : d" << EOF
+x = 2 != 2 ? c : d
+EOF
+expect <<EOF
+x = d
+EOF
+
+###############################################################################

No commit comments for this range

Something went wrong with that request. Please try again.