Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, 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
@wpwrak wpwrak parser.y: added section titles to improve readability b933013
@wpwrak wpwrak compiler: recognize ==, <, and > as aliases for equal, above, below cdc9ffe
@wpwrak 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
@wpwrak wpwrak compiler: add unary ! operator (basic support only) 369310a
@wpwrak 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
@wpwrak 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
View
2  src/compiler/compiler.c
@@ -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;
View
98 src/compiler/parser.y
@@ -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; }
View
5 src/compiler/parser_helper.c
@@ -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;
View
7 src/compiler/parser_helper.h
@@ -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 */
View
7 src/compiler/ptest/ptest.c
@@ -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();
}
View
7 src/compiler/scanner.re
@@ -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);
View
103 src/compiler/test/not
@@ -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
+
+###############################################################################
View
16 src/compiler/test/prec
@@ -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
###############################################################################
View
214 src/compiler/test/relop
@@ -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.