From: Mark Wooding Date: Sat, 10 Aug 2019 13:48:07 +0000 (+0100) Subject: test/bad.sod: Test error reporting and recovery. X-Git-Url: https://git.distorted.org.uk/~mdw/sod/commitdiff_plain/deef49564bd7cd4b9d046569fdc367457f8893a0?ds=sidebyside test/bad.sod: Test error reporting and recovery. Huh, what do you know? That `demo' item has come back again. --- diff --git a/test/Makefile.am b/test/Makefile.am index 3ffec2b..8145746 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -48,6 +48,16 @@ TESTS += test check_PROGRAMS += test -include test.c-dep test.h-dep +bad.out: bad.sod $(SOD) + $(SOD) -tc $(srcdir)/bad.sod >bad.raw-out 2>bad.raw-err; rc=$$?; \ + { sed 's/^/| /' bad.raw-out; \ + sed 's/^/* /; s,$(srcdir)/,test/,' bad.raw-err; \ + echo "; rc = $$rc"; } >$@.new && \ + mv $@.new $@ +check-local:: bad.out + diff -u $(srcdir)/bad.ref bad.out +CLEANFILES += bad.raw-out bad.raw-err bad.out + EXTRA_DIST += test.sod nodist_test_SOURCES = test.c test.h BUILT_SOURCES += $(nodist_test_SOURCES) diff --git a/test/bad.ref b/test/bad.ref new file mode 100644 index 0000000..f5d0c6b --- /dev/null +++ b/test/bad.ref @@ -0,0 +1,59 @@ +| ;; Hello from Lisp! +| ;; DEMO "foo" +* test/bad.sod:31:13: syntax error: Expected `{' but found `(' +* test/bad.sod:31:29: lexical error: Empty character literal +* test/bad.sod:31:32: lexical error: Too many characters in character literal +* test/bad.sod:33:6: syntax error: Expected but found `{' +* test/bad.sod:33:6: syntax error: Expected `:' but found `{' +* test/bad.sod:36:12: syntax error: Expected `:' but found `{' +* test/bad.sod:43:17: error: Slot declarations cannot have function type +* test/bad.sod:43:19: syntax error: Expected but found `.' +* test/bad.sod:45:2: error: No message in class `Wrong' with name `fizzbuzz' +* test/bad.sod:45:12: error: No superclass of `Wrong' with nickname `wtf' +* test/bad.sod:45:26: error: No instance slot in class `Wrong' with name `z' +* test/bad.sod:45:30: syntax error: Expected but found `=' +* test/bad.sod:45:33: error: No superclass of `Wrong' with nickname `x' +* test/bad.sod:46:29: syntax error: Expected `;' but found `{' +* test/bad.sod:46:29: syntax error: Expected `}' but found `{' +* test/bad.sod:41:13: error: Duplicate initializer for instance slot `int wrong.x' in class `Wrong' +* test/bad.sod:40:11: note: Previous definition was here +* test/bad.sod:42:13: error: Duplicate initializer for instance slot `int wrong.x' in class `Wrong' +* test/bad.sod:40:11: note: Previous definition was here +* test/bad.sod:40:2: error: Duplicate primary direct method for message `void wrong.frob(void)' in classs `Wrong' +* test/bad.sod:38:2: note: Previous definition was here +* test/bad.sod:46:29: syntax error: Expected `class', `set', `code', `typename', `import', `load', `lisp', or `demo' but found `{' +* test/bad.sod:46:49: syntax error: Expected `class', `set', `code', `typename', `import', `load', `lisp', or `demo' but found `}' +* test/bad.sod:47:0: syntax error: Expected `class', `set', `code', `typename', `import', `load', `lisp', or `demo' but found `}' +* test/bad.sod:52:30: error: Type mismatch for keyword argument `x' in methods for message `void fail.badkw(?int x)' applicable to class `Arrgh' +* test/bad.sod:54:2: note: Type `double' declared in primary direct method of `Arrgh' (defined here) +* test/bad.sod:49:43: note: Type `int' declared in message definition in `Fail' (here) +* test/bad.sod:50:21: note: Class `Fail' is a direct superclass of `Unlikely', defined here +* test/bad.sod:52:30: note: Class `Unlikely' is a direct superclass of `Arrgh', defined here +* test/bad.sod:52:30: error: Type mismatch for keyword argument `y' in methods for message `void fail.badkw(?int x)' applicable to class `Arrgh' +* test/bad.sod:51:53: note: Type `int' declared in primary direct method of `Whoops' (defined here) +* test/bad.sod:52:30: note: Class `Whoops' is a direct superclass of `Arrgh', defined here +* test/bad.sod:50:58: note: Type `double' declared in primary direct method of `Unlikely' (defined here) +* test/bad.sod:60:41: error: Duplicate nickname `sub' in superclasses of `BadNicks': used by `RSub' and `LSub' +* test/bad.sod:60:41: note: Class `RSub' is a direct superclass of `BadNicks', defined here +* test/bad.sod:60:41: note: Class `LSub' is a direct superclass of `BadNicks', defined here +* test/bad.sod:60:41: error: Duplicate nickname `join' in superclasses of `BadNicks': used by `JSuper' and `BadNicks' +* test/bad.sod:58:32: note: Class `JSuper' is a direct superclass of `LSub', defined here +* test/bad.sod:66:37: error: Ill-formed superclass graph: can't construct class precedence list for `Splinch' +* test/bad.sod:66:37: note: Class `Splinch' orders `SodObject' before `Nioj' +* test/bad.sod:64:24: note: Class `Join' orders `Left' before `SodObject' +* test/bad.sod:66:37: note: Class `Join' is a direct superclass of `Splinch', defined here +* test/bad.sod:65:24: note: Class `Nioj' orders `Nioj' before `Left' and `SodObject' +* test/bad.sod:66:37: note: Class `Nioj' is a direct superclass of `Splinch', defined here +* test/bad.sod:67:37: error: Class `Wrong' is incomplete +* test/bad.sod:67:37: error: In `Hopeless', chain-to class `Super' is not a proper superclass +* test/bad.sod:83:46: error: No obvious choice for implicit metaclass: candidates are `MyClass' and `MyOtherClass' +* test/bad.sod:78:26: note: Direct superclass `MyObject' defined here has metaclass `MyClass' +* test/bad.sod:82:58: note: Direct superclass `MyOtherObject' defined here has metaclass `MyOtherClass' +* test/bad.sod:83:46: error: Metaclass `MyClass' of `WhichMetaClass' isn't a subclass of `MyOtherClass' +* test/bad.sod:82:58: note: Direct superclass `MyOtherObject' defined here has metaclass `MyOtherClass' +* test/bad.sod:88:0: error: Class `dismissed' is incomplete +* test/bad.sod:88:0: syntax error: Expected `{' but found `;' +* test/bad.sod:88:0: syntax error: Expected `}' but found `;' +* test/bad.sod:88:0: syntax error: Expected `class', `set', `code', `typename', `import', `load', `lisp', or `demo' but found `;' +* sod: Finished with 34 errors +; rc = 2 diff --git a/test/bad.sod b/test/bad.sod new file mode 100644 index 0000000..4ca273e --- /dev/null +++ b/test/bad.sod @@ -0,0 +1,88 @@ +/* -*-sod-*- + * + * A file full of terribleness, to check error reporting and recovery. + * + * (c) 2019 Straylight/Edgeware + */ + +/* The reference file for this test isn't intended to be normative: it's fine + * if things are reordered, or messages are rephrased. But it's good to know + * when these things change, and besides this approach is way easier than the + * alternatives. + */ + +typename Bad; + +import "chimaera"; + +lisp ;this is actually a comment + (format t ";; Hello from Lisp!~%") + /* and this is the statement terminator */; + +lisp +(define-pluggable-parser module test (scanner pset) + ;; `demo' string `;' + (declare (ignore pset)) + (with-parser-context (token-scanner-context :scanner scanner) + (parse (seq ("demo" (string (must :string)) (nil (must #\;))) + (format t ";; DEMO ~S~%" string))))); +demo "foo"; + +code c: user ( not like this '' 'xyz' ); + +class { +} + +class Wrong { + void frob() { ... } + void wrong.frob() { ... } + + int x = 2; + wrong.x = 7; + wrong.x = 3; + int filler, y(), .z[45], q; + int wrong.fizzbuzz(int n) extern; + wtf.y = 19, wrong.z = 69, x.= r; + int (*bogon)(const char *) { return strlen(p); } +} + +class Fail: SodObject { void badkw(?int x) extern; void ebw(?) extern; } +class Unlikely: Fail { void fail.badkw(?double y) extern; } +class Whoops: Fail { void fail.badkw(?int y) extern; } +class Arrgh: Unlikely, Whoops { + void fail.badkw(?double x) extern; + void fail.ebw(?) extern; +} + +[nick = join] class JSuper: SodObject { } +[nick = sub] class LSub: JSuper { } +[nick = sub] class RSub: JSuper { } +[nick = join] class BadNicks: LSub, RSub { } +class Super: SodObject { } +class Left: Super { } +class Right: Super { } +class Join: Left, Right { } +class Nioj: Right, Left { } +class Splinch: Join, SodObject, Nioj { } +[link = Super] class Hopeless: Wrong { } + +[link = SodClass] +class MyClass: SodClass { + int foo = 1; + int bar = 2; +} + +class MyOtherClass: SodClass { } + +[metaclass = MyClass, link = SodObject] +class MyObject: SodObject { + class myclass.foo = 42; +} + +[metaclass = MyOtherClass] class MyOtherObject: SodObject { } +class WhichMetaClass: MyObject, MyOtherObject { } + +class dismissed; + +class hopeful: dismissed +;