]> ocean-lang.org Git - ocean/blobdiff - csrc/oceani-tests.mdc
oceani: free variables as soon as they go out of scope.
[ocean] / csrc / oceani-tests.mdc
index d5541e9c3e21ea27ddb418d666789d8062c60beb..dccfb2a47bc2bdb50f7f3a39e7c3adf09ccf1b01 100644 (file)
@@ -80,11 +80,11 @@ arguments separated from the name by commas.  For each test, there is a section
                @mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage || true
                @ awk '/NOTEST/ { next } /^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \
                    END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \
                @mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage || true
                @ awk '/NOTEST/ { next } /^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \
                    END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \
-                        if (ran < (ran + skip) *0.94) exit(1) }' \
+                        if (ran < (ran + skip) *0.959) exit(1) }' \
                        coverage/oceani.mdc.gcov
                @rm -f .tmp*
 
                        coverage/oceani.mdc.gcov
                @rm -f .tmp*
 
-               @for T in $(oceani_tests); do \
+               @[ -n "$$SKIP_VALGRIND" ] || for T in $(oceani_tests); do \
                    echo -n "Valgrind $$T.. "; \
                    i="$$IFS"; IFS=,; set $$T; IFS="$$i"; t=$$1; shift; \
                    if ! valgrind --error-exitcode=1 --log-file=.tmp.valg ./oceani --section "test: $$t" oceani-tests.mdc $${1+"$$@"} \
                    echo -n "Valgrind $$T.. "; \
                    i="$$IFS"; IFS=,; set $$T; IFS="$$i"; t=$$1; shift; \
                    if ! valgrind --error-exitcode=1 --log-file=.tmp.valg ./oceani --section "test: $$t" oceani-tests.mdc $${1+"$$@"} \
@@ -110,7 +110,9 @@ calculations on them.
 
 ###### test: valvar
 
 
 ###### test: valvar
 
-       program:
+       func main
+               argv:[argc::]string
+       do
                a := 23; b:=12 ; b1 := -b
                print a, b, a+b, a-b, a*b, a/b, a%b
                print a<b, a<=b, a>b, a>=b, a<a, a==b, a==a
                a := 23; b:=12 ; b1 := -b
                print a, b, a+b, a-b, a*b, a/b, a%b
                print a<b, a<=b, a>b, a>=b, a<a, a==b, a==a
@@ -147,7 +149,7 @@ Next we change the value of variables
 
 ###### test: setvar
 
 
 ###### test: setvar
 
-       program:
+       func main()
                a := 4
                a = a * a
                a = (a + a) * (a + a)
                a := 4
                a = a * a
                a = (a + a) * (a + a)
@@ -170,7 +172,7 @@ Now some contants
                cake ::= "The cake is"
                  ++ " a lie"
 
                cake ::= "The cake is"
                  ++ " a lie"
 
-       program:
+       func main()
                print "Hello World, what lovely oceans you have!"
                print "are there", five, "?"
                print pi, pie, "but", cake
                print "Hello World, what lovely oceans you have!"
                print "are there", five, "?"
                print pi, pie, "but", cake
@@ -187,7 +189,17 @@ Test merging of variables from multiple cases
 
 ###### test: varmerge
 
 
 ###### test: varmerge
 
-       program:
+       func main()
+               for i:=0; then i=i+1; while i < 5:
+                       switch i:
+                               case 0: num:="zero"
+                               case 1: scratch:=42; num:="one"
+                               case 2: num:="two"
+                               case 3: num:="three"
+                               else    num:="many"
+                       print num,", ",
+               print
+
                for i:=0; then i=i+1; while i < 5:
                        switch i:
                                case 0: num:="zero"
                for i:=0; then i=i+1; while i < 5:
                        switch i:
                                case 0: num:="zero"
@@ -195,11 +207,14 @@ Test merging of variables from multiple cases
                                case 2: num:="two"
                                case 3: num:="three"
                                else    num:="many"
                                case 2: num:="two"
                                case 3: num:="three"
                                else    num:="many"
+                       // re-declare a CondScope variable
+                       num := i*i
                        print num,", ",
                print
 
 ###### output: varmerge
        zero , one , two , three , many , 
                        print num,", ",
                print
 
 ###### output: varmerge
        zero , one , two , three , many , 
+       0 , 1 , 4 , 9 , 16 , 
 
 ## Conditions and Loops
 
 
 ## Conditions and Loops
 
@@ -210,7 +225,7 @@ Now we need to test if/else and some different loops
 
 ###### test: cond_loop
 
 
 ###### test: cond_loop
 
-       program:
+       func main()
                a := 4
                if a < 5:
                        print "Success"
                a := 4
                if a < 5:
                        print "Success"
@@ -252,6 +267,13 @@ Now we need to test if/else and some different loops
                else
                        pass
                        print "sum 1..10 is", sum
                else
                        pass
                        print "sum 1..10 is", sum
+               if
+                       PI1 := 22/7
+                       use PI1 < pi
+               then
+                       print "Smaller"
+               else
+                       print 'larger'
 
 ###### output: cond_loop
        Success
 
 ###### output: cond_loop
        Success
@@ -270,6 +292,7 @@ Now we need to test if/else and some different loops
        pi exceeds three
        pi sufficient
        sum 1..10 is 55
        pi exceeds three
        pi sufficient
        sum 1..10 is 55
+       larger
 
 ## Say Hello
 
 
 ## Say Hello
 
@@ -282,9 +305,10 @@ Here I break it into two parts, keeping the array code separate.
 
 ###### test: sayhello
 
 
 ###### test: sayhello
 
-       program As Bs astr bbools:
-               A := $As; B := $Bs
-               bbool := bbools == "True"
+       func main(av:[ac::number]string)
+               A := $av[1]; B := $av[2]
+               astr := av[3]
+               bbool := av[ac-1] == "True"
                print "Hello World, what lovely oceans you have!"
                /* When a variable is defined in both branches of an 'if',
                 * and used afterwards, the variables are merged.
                print "Hello World, what lovely oceans you have!"
                /* When a variable is defined in both branches of an 'if',
                 * and used afterwards, the variables are merged.
@@ -307,6 +331,7 @@ Here I break it into two parts, keeping the array code separate.
                a : number
                a = A;
                b:number = B
                a : number
                a = A;
                b:number = B
+               print "still", bigger // check for regression in scoping
                if a > 0 and b > 0:
                        while a != b:
                                if a < b:
                if a > 0 and b > 0:
                        while a != b:
                                if a < b:
@@ -349,18 +374,20 @@ Here I break it into two parts, keeping the array code separate.
                        else
                                hi = mid
                        if hi - lo < 1:
                        else
                                hi = mid
                        if hi - lo < 1:
+                               lo = mid
                                use GiveUp
                        use True
                do pass
                case Found:
                        print "Yay, I found", target
                case GiveUp:
                                use GiveUp
                        use True
                do pass
                case Found:
                        print "Yay, I found", target
                case GiveUp:
-                       print "Closest I found was", mid
+                       print "Closest I found was", lo
 
 ###### output: sayhello,55,33,hello,True
        Hello World, what lovely oceans you have!
        Is 55 bigger than 33 ?  yes
        double 33 is 66
 
 ###### output: sayhello,55,33,hello,True
        Hello World, what lovely oceans you have!
        Is 55 bigger than 33 ?  yes
        double 33 is 66
+       still yes
        GCD of 55 and 33 is 11
        Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144
        hello was the str
        GCD of 55 and 33 is 11
        Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144
        hello was the str
@@ -370,6 +397,7 @@ Here I break it into two parts, keeping the array code separate.
        Hello World, what lovely oceans you have!
        Is 12 bigger than 60 ?  no
        double 60 is 120
        Hello World, what lovely oceans you have!
        Is 12 bigger than 60 ?  no
        double 60 is 120
+       still no
        GCD of 12 and 60 is 12
        Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144
        I found the str over there
        GCD of 12 and 60 is 12
        Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144
        I found the str over there
@@ -378,7 +406,7 @@ Here I break it into two parts, keeping the array code separate.
 ###### test list
        oceani_tests += "insert_sort"
 ###### test: insert_sort
 ###### test list
        oceani_tests += "insert_sort"
 ###### test: insert_sort
-       program:
+       func main()
                size::=55
                list:[size]number
                list[0] = 1_234
                size::=55
                list:[size]number
                list[0] = 1_234
@@ -524,7 +552,7 @@ ad-hoc things array related.
 
 ###### test: arrays
 
 
 ###### test: arrays
 
-       program:
+       func main()
                bools:[5]Boolean
                strings:[4]string
 
                bools:[5]Boolean
                strings:[4]string
 
@@ -559,7 +587,8 @@ Time to test if structure declarations and accesses work correctly.
 
        struct baz { a:number; b:Boolean; }
 
 
        struct baz { a:number; b:Boolean; }
 
-       program:
+       func main
+       do
                info:[4]foo
 
                for i:=0; then i=i+1; while i < 4:
                info:[4]foo
 
                for i:=0; then i=i+1; while i < 4:
@@ -620,14 +649,14 @@ separate file first, then run from there.
 
 ###### test: syn1
 
 
 ###### test: syn1
 
-       program:
+       func main()
                if then else while do
 
 ###### output: syn1
        .tmp.code:3:11: Syntax error in statement: then
 
 ###### test: tokerr
                if then else while do
 
 ###### output: syn1
        .tmp.code:3:11: Syntax error in statement: then
 
 ###### test: tokerr
-       program:
+       func main()
                a := 1i  // imaginary numbers aren't understood
                b:[2i]number // array sizes are handled separately
                c:[3.14159]Boolean // array sizes must be integers
                a := 1i  // imaginary numbers aren't understood
                b:[2i]number // array sizes are handled separately
                c:[3.14159]Boolean // array sizes must be integers
@@ -677,7 +706,7 @@ various places that `type_err()` are called.
 
 ###### test: type_err1
 
 
 ###### test: type_err1
 
-       program:
+       func main()
                print "hello" ++ 5, 5 ++ "hello"
 
                b ::= 3
                print "hello" ++ 5, 5 ++ "hello"
 
                b ::= 3
@@ -697,7 +726,7 @@ various places that `type_err()` are called.
 
 ###### test: type_err2
 
 
 ###### test: type_err2
 
-       program:
+       func main()
                a := 1
                a := 2
                a ::= 3
                a := 1
                a := 2
                a ::= 3
@@ -722,7 +751,7 @@ various places that `type_err()` are called.
                a: number
                b:string = "hello"
 
                a: number
                b:string = "hello"
 
-       program:
+       func main()
                c := "hello"
                c = c + 1
                c = "hello" ++ (True and False)
                c := "hello"
                c = c + 1
                c = "hello" ++ (True and False)
@@ -750,6 +779,14 @@ various places that `type_err()` are called.
                bar:foo
                foo.c = 43
                print c.foo
                bar:foo
                foo.c = 43
                print c.foo
+               print bar.c
+               print bar.b + 42
+               
+
+               // trigger 'labels not permitted' error message
+               while 1 if True else False:
+                       print
+               case 2: print "two"
 
 ###### output: type_err3
        .tmp.code:8:12: error: expected number but variable 'c' is string
 
 ###### output: type_err3
        .tmp.code:8:12: error: expected number but variable 'c' is string
@@ -779,10 +816,13 @@ various places that `type_err()` are called.
        .tmp.code:32:8: error: field reference attempted on none, not a struct
        .tmp.code:32:16: error: expected none found number
        .tmp.code:33:14: error: field reference attempted on string, not a struct
        .tmp.code:32:8: error: field reference attempted on none, not a struct
        .tmp.code:32:16: error: expected none found number
        .tmp.code:33:14: error: field reference attempted on string, not a struct
+       .tmp.code:34:14: error: cannot find requested field in foo
+       .tmp.code:35:17: error: have string but need number
+       .tmp.code:39:29: error: expected number (labels not permitted) found Boolean
        oceani: type error in program - not running.
 
 ###### test: type_err4
        oceani: type error in program - not running.
 
 ###### test: type_err4
-       program:
+       func main()
                a:=1; b=2; c::=3
                print a, b, c
 
                a:=1; b=2; c::=3
                print a, b, c
 
@@ -793,7 +833,7 @@ various places that `type_err()` are called.
        oceani: type error in program - not running.
 
 ###### test list
        oceani: type error in program - not running.
 
 ###### test list
-       oceani_failing_tests += type_err_const type_err_const1
+       oceani_failing_tests += type_err_const type_err_const1 missing_program
 
 ###### test: type_err_const
        const
 
 ###### test: type_err_const
        const
@@ -801,22 +841,30 @@ various places that `type_err()` are called.
                bar ::= "string" + 56
        const
                bar ::= "baz"
                bar ::= "string" + 56
        const
                bar ::= "baz"
-       program:
+       func main()
                foo := 4
                print foo, bar
 
                foo := 4
                print foo, bar
 
+       // trigger duplicate-main error
+       func main()
+               foo := 6
+               print bar, foo
+
 ###### 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
 ###### 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
+       .tmp.code:13:8: error: variable 'foo' redeclared
+       .tmp.code:3:8: info: this is where 'foo' was first declared
+       .tmp.code:13:8: "main" defined a second time
 
 ###### test: type_err_const1
        const
                foo : number = 45
                bar := "string"
 
 ###### test: type_err_const1
        const
                foo : number = 45
                bar := "string"
-       program:
+       func main()
                foo := 4
                print foo, bar
 
                foo := 4
                print foo, bar
 
@@ -824,6 +872,13 @@ various places that `type_err()` are called.
        .tmp.code:3:12: Syntax error in constant: :
        .tmp.code:4:12: Syntax error in constant: :
 
        .tmp.code:3:12: Syntax error in constant: :
        .tmp.code:4:12: Syntax error in constant: :
 
+###### test: missing_program
+       const
+               foo::="bar"
+
+###### output: missing_program
+       oceani: no main function found.
+
 ## Test erroneous command line args
 
 To improve coverage, we want to test correct handling of strange command
 ## Test erroneous command line args
 
 To improve coverage, we want to test correct handling of strange command