do
pass
+ func twoarg
+ a:number
+ b:string
+ do
+ while a > 0:
+ print b
+ a = a - 1
+
func test(n:number; s:string)
if n >= 1:
print n,s,
func test2(a:number; b:string; c:[3]Boolean)
print a, b, c[1]
+ func test3()
+ # use undefined names
+ print a, z
+
func main()
truth:[3]Boolean
truth[1] = True
pass
###### output: func_err_args
- .tmp.code:11:14: error: insufficient arguments to function.
- .tmp.code:12:14: error: expected number found string
- .tmp.code:12:22: error: expected string found number
- .tmp.code:12:14: error: insufficient arguments to function.
- .tmp.code:14:17: error: expected string found number
- .tmp.code:15:14: error: too many arguments to function.
- .tmp.code:16:14: error: attempt to call a non-function.
- .tmp.code:16:32: error: expected string found number
- .tmp.code:16:28: error: insufficient arguments to function.
- .tmp.code:17:20: error: expected func but variable 'test2' is func
+ .tmp.code:15:14: error: insufficient arguments to function.
+ .tmp.code:16:14: error: expected number found string
+ .tmp.code:16:22: error: expected string found number
+ .tmp.code:16:14: error: insufficient arguments to function.
+ .tmp.code:18:17: error: expected string found number
+ .tmp.code:19:14: error: too many arguments to function.
+ .tmp.code:20:14: error: attempt to call a non-function.
+ .tmp.code:20:32: error: expected string found number
+ .tmp.code:20:28: error: insufficient arguments to function.
+ .tmp.code:21:20: error: expected func but variable 'test2' is func
.tmp.code:??:??: info: this is where 'NOTVAR' was set to func
+ .tmp.code:10:14: error: variable used but not declared: a
+ .tmp.code:10:17: error: variable used but not declared: z
oceani: type error in program - not running.
###### test: func_err_redeclare
As yet these types cannot be declared separately from the function
itself.
-The parameters can be specified either in parentheses as a list, such as
+The parameters can be specified either in parentheses as a ';' separated
+list, such as
##### Example: function 1
- func main(av:[ac::number]string)
+ func main(av:[ac::number]string; env:[envc::number]string)
code block
-or as an indented list of one parameter per line
+or as an indented list of one parameter per line (though each line can
+be a ';' separated list)
##### Example: function 2
func main
argv:[argc::number]string
+ env:[envc::number]string
do
code block
$*binode
- Args -> ${ $0 = NULL; }$
+ Args -> ArgsLine NEWLINE ${ $0 = $<AL; }$
+ | Args ArgsLine NEWLINE ${ {
+ struct binode *b = $<AL;
+ struct binode **bp = &b;
+ while (*bp)
+ bp = (struct binode **)&(*bp)->left;
+ *bp = $<A;
+ $0 = b;
+ } }$
+
+ ArgsLine -> ${ $0 = NULL; }$
| Varlist ${ $0 = $<1; }$
| Varlist ; ${ $0 = $<1; }$
- | Varlist NEWLINE ${ $0 = $<1; }$
- Varlist -> Varlist ; ArgDecl ${ // UNTESTED
+ Varlist -> Varlist ; ArgDecl ${
$0 = new(binode);
$0->op = List;
$0->left = $<Vl;
###### top level grammar
$*variable
- DeclareFunction -> func FuncName ( OpenScope Args ) Block Newlines ${
+ DeclareFunction -> func FuncName ( OpenScope ArgsLine ) Block Newlines ${
$0 = declare_function(c, $<FN, $<Ar, $<Bl);
}$
- | func FuncName IN OpenScope OptNL Args OUT OptNL do Block Newlines ${
+ | func FuncName IN OpenScope Args OUT OptNL do Block Newlines ${
$0 = declare_function(c, $<FN, $<Ar, $<Bl);
}$
| func FuncName NEWLINE OpenScope OptNL do Block Newlines ${
static int analyse_funcs(struct parse_context *c)
{
struct variable *v;
- int ok = 1;
- for (v = c->in_scope; ok && v; v = v->in_scope) {
+ int all_ok = 1;
+ for (v = c->in_scope; v; v = v->in_scope) {
struct value *val;
+ int ok = 1;
if (v->depth != 0 || !v->type || !v->type->check_args)
continue;
val = var_value(c, v);
if (ok)
/* Make sure everything is still consistent */
propagate_types(val->function, c, &ok, Tnone, 0);
+ if (!ok)
+ all_ok = 0;
v->type->function.local_size = scope_finalize(c);
}
- return ok;
+ return all_ok;
}
static int analyse_main(struct type *type, struct parse_context *c)