###### output: setvar
1.07374e+09 1
+Now some contants
+
+###### test list
+ oceani_tests += "consts"
+
+###### test: consts
+ const:
+ pi ::= 3.1415926
+ four ::= 2 + 2 ; five ::= 10/2
+ const pie ::= "I like Pie";
+ cake ::= "The cake is"
+ ++ " a lie"
+
+ program:
+ print "Hello World, what lovely oceans you have!"
+ print "are there", five, "?"
+ print pi, pie, "but", cake
+
+###### output: consts
+ Hello World, what lovely oceans you have!
+ are there 5 ?
+ 3.14159 I like Pie but The cake is a lie
+
## Conditions and Loops
Now we need to test if/else and some different loops
.tmp.code:3:14: info: this is where 'b' was set to label
oceani: type error in program - not running.
+###### test list
+ oceani_failing_tests += type_err_const type_err_const1
+
+###### test: type_err_const
+ const:
+ foo :: number = 45
+ bar ::= "string" + 56
+ const:
+ bar ::= "baz"
+ program:
+ foo := 4
+ print foo, bar
+
+###### output: type_err_const
+ .tmp.code:4:16: error: expected number found string
+ .tmp.code:6:8: error: name already declared: bar
+ .tmp.code:4:8: info: this is where 'bar' was first declared
+ .tmp.code:8:8: error: variable 'foo' redeclared
+ .tmp.code:3:8: info: this is where 'foo' was first declared
+
+###### test: type_err_const1
+ const:
+ foo : number = 45
+ bar := "string"
+ program:
+ foo := 4
+ print foo, bar
+
+###### output: type_err_const1
+ .tmp.code:3:12: error: unhandled parse error: :
+ oceani: no program found.
+
+
## Test erroneous command line args
To improve coverage, we want to test correct handling of strange command
v = t->previous;
free_value(t->val);
+ if (t->min_depth == 0)
+ free_exec(t->where_decl);
free(t);
}
}
## top level grammar
+### The `const` section
+
+As well as being defined in with the code that uses them, constants
+can be declared at the top level. These have full-file scope, so they
+are always `InScope`. The value of a top level constant can be given
+as an expression, and this is evaluated immediately rather than in the
+later interpretation stage. Once we add functions to the language, we
+will need rules concern which, if any, can be used to define a top
+level constant.
+
+Constants are defined in a sectiont that starts with the reserved word
+`const` and then has a block with a list of assignment statements.
+For syntactic consistency, these must use the double-colon syntax to
+make it clear that they are constants. Type can also be given: if
+not, the type will be determined during analysis, as with other
+constants.
+
+###### top level grammar
+
+ DeclareConstant -> const Open ConstList Close
+ | const Open Newlines ConstList Close
+ | const Open SimpleConstList }
+ | const Open Newlines SimpleConstList }
+ | const : ConstList
+ | const SimpleConstList
+
+ ConstList -> ComplexConsts
+ ComplexConsts -> ComplexConst ComplexConsts
+ | ComplexConst
+ ComplexConst -> SimpleConstList NEWLINE
+ SimpleConstList -> Const ; SimpleConstList
+ | Const
+ | Const ; SimpleConstList ;
+
+ $*type
+ CType -> Type ${ $0 = $<1; }$
+ | ${ $0 = NULL; }$
+ $void
+ Const -> IDENTIFIER :: CType = Expression ${ {
+ int ok;
+ struct variable *v;
+
+ v = var_decl(config2context(config), $1.txt);
+ if (v) {
+ struct var *var = new_pos(var, $1);
+ v->where_decl = var;
+ v->where_set = var;
+ var->var = v;
+ v->constant = 1;
+ } else {
+ v = var_ref(config2context(config), $1.txt);
+ tok_err(config2context(config), "error: name already declared", &$1);
+ type_err(config2context(config), "info: this is where '%v' was first declared",
+ v->where_decl, NULL, 0, NULL);
+ }
+ do {
+ ok = 1;
+ propagate_types($5, config2context(config), &ok, $3, 0);
+ } while (ok == 2);
+ if (!ok)
+ config2context(config)->parse_error = 1;
+ else if (v) {
+ v->val = interp_exec($5);
+ }
+ } }$
+
+
### Finally the whole program.
Somewhat reminiscent of Pascal a (current) Ocean program starts with
###### test: hello
+ const:
+ pi ::= 3.1415926
+ four ::= 2 + 2 ; five ::= 10/2
+ const pie ::= "I like Pie";
+ cake ::= "The cake is"
+ ++ " a lie"
+
program A B:
print "Hello World, what lovely oceans you have!"
+ print "are there", five, "?"
+ print pi, pie, "but", cake
+
/* When a variable is defined in both branches of an 'if',
* and used afterwards, the variables are merged.
*/