]> ocean-lang.org Git - ocean/commitdiff
oceani: fix parsing for function declaration parameters
authorNeilBrown <neil@brown.name>
Fri, 12 Nov 2021 22:02:19 +0000 (09:02 +1100)
committerNeilBrown <neil@brown.name>
Sat, 13 Nov 2021 22:50:58 +0000 (09:50 +1100)
Multiple lines of declarations weren't handle properly.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/oceani-tests.mdc
csrc/oceani.mdc

index 2314ce3ea4d9ec070c7cf23867f04f3072fd71b3..78b458b3a455adf33dae58958dccea7e15fe40b1 100644 (file)
@@ -630,6 +630,14 @@ Test functions.  They don't return anything, so we need to get them to print
        do
                pass
 
        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 test(n:number; s:string)
                if n >= 1:
                        print n,s,
@@ -936,6 +944,10 @@ Test for type errors with functions
        func test2(a:number; b:string; c:[3]Boolean)
                print a, b, c[1]
 
        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
        func main()
                truth:[3]Boolean
                truth[1] = True
@@ -949,17 +961,19 @@ Test for type errors with functions
                        pass
 
 ###### output: func_err_args
                        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:??:??: 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
        oceani: type error in program - not running.
 
 ###### test: func_err_redeclare
index c89ecafc6c33890f838890eceb91b815e07575f3..fabfe188c07ebd5bc9abdca9dd492aad34041de2 100644 (file)
@@ -2340,19 +2340,22 @@ has a type which includes the set of parameters and the return value.
 As yet these types cannot be declared separately from the function
 itself.
 
 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
 
 
 ##### Example: function 1
 
-       func main(av:[ac::number]string)
+       func main(av:[ac::number]string; env:[envc::number]string)
                code block
 
                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
 
 ##### Example: function 2
 
        func main
                argv:[argc::number]string
+               env:[envc::number]string
        do
                code block
 
        do
                code block
 
@@ -2479,12 +2482,21 @@ further detailed when Expression Lists are introduced.
 
 
        $*binode
 
 
        $*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 ${ $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;
                        $0 = new(binode);
                        $0->op = List;
                        $0->left = $<Vl;
@@ -4725,10 +4737,10 @@ analysis is a bit more interesting at this level.
 ###### top level grammar
 
        $*variable
 ###### 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);
                }$
                        $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 ${
                        $0 = declare_function(c, $<FN, $<Ar, $<Bl);
                }$
                | func FuncName NEWLINE OpenScope OptNL do Block Newlines ${
@@ -4770,9 +4782,10 @@ analysis is a bit more interesting at this level.
        static int analyse_funcs(struct parse_context *c)
        {
                struct variable *v;
        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;
                        struct value *val;
+                       int ok = 1;
                        if (v->depth != 0 || !v->type || !v->type->check_args)
                                continue;
                        val = var_value(c, v);
                        if (v->depth != 0 || !v->type || !v->type->check_args)
                                continue;
                        val = var_value(c, v);
@@ -4783,9 +4796,11 @@ analysis is a bit more interesting at this level.
                        if (ok)
                                /* Make sure everything is still consistent */
                                propagate_types(val->function, c, &ok, Tnone, 0);
                        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);
                }
                        v->type->function.local_size = scope_finalize(c);
                }
-               return ok;
+               return all_ok;
        }
 
        static int analyse_main(struct type *type, struct parse_context *c)
        }
 
        static int analyse_main(struct type *type, struct parse_context *c)