### Expressions: The rest
-The remaining expressions with the highest precedence are arithmetic and
-string concatenation. String concatenation (`++`) has the same
-precedence as multiplication and division, but lower than the uniary.
+The remaining expressions with the highest precedence are arithmetic,
+string concatenation, and string conversion. String concatenation
+(`++`) has the same precedence as multiplication and division, but lower
+than the uniary.
+
+String conversion is a temporary feature until I get a better type
+system. `$` is a prefix operator which expects a string and returns
+a number.
`+` and `-` are both infix and prefix operations (where they are
absolute value and negation). These have different operator names.
Times, Divide, Rem,
Concat,
Absolute, Negate,
+ StringConv,
Bracket,
###### expr precedence
$LEFT + - Eop
$LEFT * / % ++ Top
- $LEFT Uop
+ $LEFT Uop $
$TERM ( )
###### expression grammar
Uop -> + ${ $0.op = Absolute; }$
| - ${ $0.op = Negate; }$
+ | $ ${ $0.op = StringConv; }$
Top -> * ${ $0.op = Times; }$
| / ${ $0.op = Divide; }$
if (bracket) printf(")");
break;
case Absolute:
- if (bracket) printf("(");
- printf("+");
- print_exec(b->right, indent, bracket);
- if (bracket) printf(")");
- break;
case Negate:
+ case StringConv:
if (bracket) printf("(");
- printf("-");
+ switch (b->op) {
+ case Absolute: fputs("+", stdout); break;
+ case Negate: fputs("-", stdout); break;
+ case StringConv: fputs("$", stdout); break;
+ default: abort(); // NOTEST
+ } // NOTEST
print_exec(b->right, indent, bracket);
if (bracket) printf(")");
break;
Tstr, rules, type);
return Tstr;
+ case StringConv:
+ /* op must be string, result is number */
+ propagate_types(b->left, c, ok, Tstr, 0);
+ if (!type_compat(type, Tnum, 0))
+ type_err(c,
+ "error: Can only convert string to number, not %1",
+ prog, type, 0, NULL);
+ return Tnum;
+
case Bracket:
return propagate_types(b->right, c, ok, type, 0);
rvtype = Tstr;
rv.str = text_join(left.str, right.str);
break;
+ case StringConv:
+ right = interp_exec(b->right, &rvtype);
+ rtype = Tstr;
+ rvtype = Tnum;
+ char *str = strndup(right.str.txt, right.str.len);
+ parse_value(rvtype, str, &rv);
+ free(str);
+ break;
###### value functions
name:string
alive:Boolean
- program A B:
+ program Astr Bstr:
print "Hello World, what lovely oceans you have!"
print "Are there", five, "?"
print pi, pie, "but", cake
+ A := $Astr; B := $Bstr
+
/* When a variable is defined in both branches of an 'if',
* and used afterwards, the variables are merged.
*/