From 6f3c6db8d0e5c5bf244f9a101e72e5e498b5fb6d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 9 May 2019 21:13:16 +1000 Subject: [PATCH] oceani: add conditional expression [value] if [condition] else [alternate value] is a conditional expression which will only evaluate and return one of the two values, depending on the condition. This has lowest precedence of all expressions. Signed-off-by: NeilBrown --- csrc/oceani-tests.mdc | 2 + csrc/oceani.mdc | 90 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/csrc/oceani-tests.mdc b/csrc/oceani-tests.mdc index b2c2e1b..d5e60b7 100644 --- a/csrc/oceani-tests.mdc +++ b/csrc/oceani-tests.mdc @@ -165,6 +165,7 @@ Now we need to test if/else and some different loops pi ::= 3.1415926535897 if 355/113 == pi or else +(pi - 355/113) < 0.001: print "Close enough" + print "lower" if 355/113 < pi else "higher" ###### output: cond_loop Success @@ -179,6 +180,7 @@ Now we need to test if/else and some different loops 20 / 6 = 3.33333 I won't calculate 20 / 9 Close enough + higher ## Say Hello diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 123fffc..07caefa 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -1861,16 +1861,86 @@ link to find the primary instance. ###### free exec cases case Xvar: free_var(cast(var, e)); break; +### Expressions: Conditional + +Our first user of the `binode` will be conditional expressions, which +is a bit odd as they actually have three components. That will be +handled by having 2 binodes for each expression. The conditional +expression is the lowest precedence operatior, so it gets to define +what an "Expression" is. The next level up is "BoolExpr", which +comes next. + +Conditional expressions are of the form "value `if` condition `else` +other_value". There is no associativite with this operator: the +values and conditions can only be other conditional expressions if +they are enclosed in parentheses. Allowing nesting without +parentheses would be too confusing. + +###### Binode types + CondExpr, + +###### Grammar + + $*exec + Expression -> BoolExpr if BoolExpr else BoolExpr ${ { + struct binode *b1 = new(binode); + struct binode *b2 = new(binode); + b1->op = CondExpr; + b1->left = $<3; + b1->right = b2; + b2->op = CondExpr; + b2->left = $<1; + b2->right = $<5; + $0 = b1; + } }$ + | BoolExpr ${ $0 = $<1; }$ + +###### print binode cases + + case CondExpr: + b2 = cast(binode, b->right); + print_exec(b2->left, -1, 0); + printf(" if "); + print_exec(b->left, -1, 0); + printf(" else "); + print_exec(b2->right, -1, 0); + break; + +###### propagate binode cases + + case CondExpr: { + /* cond must be Tbool, others must match */ + struct binode *b2 = cast(binode, b->right); + struct type *t2; + + propagate_types(b->left, c, ok, Tbool, 0); + t = propagate_types(b2->left, c, ok, type, Rnolabel); + t2 = propagate_types(b2->right, c, ok, type ?: t, Rnolabel); + return t ?: t2; + } + +###### interp binode cases + + case CondExpr: { + struct binode *b2 = cast(binode, b->right); + left = interp_exec(b->left); + if (left.bool) + rv = interp_exec(b2->left); + else + rv = interp_exec(b2->right); + } + break; + ### Expressions: Boolean -Our first user of the `binode` will be expressions, and particularly -Boolean expressions. As I haven't implemented precedence in the -parser generator yet, we need different names for each precedence -level used by expressions. The outer most or lowest level precedence -are Boolean operators which form an `Expression` out of `BTerm`s and -`BFact`s. As well as `or` `and`, and `not` we have `and then` and `or -else` which only evaluate the second operand if the result would make -a difference. +The next class of expressions to use the `binode` will be Boolean +expressions. As I haven't implemented precedence in the parser +generator yet, we need different names for each precedence level used +by expressions. The outer most or lowest level precedence are +conditional expressions are Boolean operators which form an `BoolExpr` +out of `BTerm`s and `BFact`s. As well as `or` `and`, and `not` we +have `and then` and `or else` which only evaluate the second operand +if the result would make a difference. ###### Binode types And, @@ -1882,14 +1952,14 @@ a difference. ###### Grammar $*exec - Expression -> Expression or BTerm ${ { + BoolExpr -> BoolExpr or BTerm ${ { struct binode *b = new(binode); b->op = Or; b->left = $<1; b->right = $<3; $0 = b; } }$ - | Expression or else BTerm ${ { + | BoolExpr or else BTerm ${ { struct binode *b = new(binode); b->op = OrElse; b->left = $<1; -- 2.43.0