+ # Parse a super class declaration
+ # Fatal error if the `string` is not a syntactically correct super class declaration
+ fun parse_superclass(string: String): APropdef
+ do
+ var mod_string = "class Dummy\nsuper {string}\nend"
+ var nclassdef = parse_classdef(mod_string).as(AStdClassdef)
+ var nsuperclasses = nclassdef.n_propdefs
+ if nsuperclasses.length != 1 then
+ self.fatal_error(null, "Fatal Error: not a super class declaration.")
+ abort
+ end
+ return nsuperclasses.first
+ end
+
+ # Try to parse the `string` as something
+ #
+ # Returns the first possible syntacticaly correct type among:
+ #
+ # - a type `AType`
+ # - a single `Token`
+ # - an expression `AExpr`
+ # - a block of statements `ABlockExpr`
+ # - a full module `AModule`
+ # - a `AError` if nothing else matches
+ #
+ # var tc = new ToolContext
+ # assert tc.parse_something("foo") isa TId
+ # assert tc.parse_something("foo[bar]") isa AExpr
+ # assert tc.parse_something("Foo[Bar]") isa AType
+ # assert tc.parse_something("foo\nbar") isa ABlockExpr
+ # assert tc.parse_something("fun foo do bar\nfoo") isa AModule
+ # assert tc.parse_something("fun fun") isa AParserError
+ # assert tc.parse_something("?%^&") isa ALexerError
+ fun parse_something(string: String): ANode
+ do
+ var source = new SourceFile.from_string("", string)
+ var error
+ var tree
+ var eof
+ var lexer
+
+ lexer = new InjectedLexer(source)
+ lexer.injected_before.add new TKwvar
+ lexer.injected_before.add new TId
+ lexer.injected_before.add new TColumn
+ lexer.injected_before.add new TClassid
+ lexer.injected_before.add new TObra
+ lexer.injected_after.add new TCbra
+ tree = (new Parser(lexer)).parse
+ eof = tree.n_eof
+ if not eof isa AError then
+ var ntype = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_type.n_types.first
+ ntype.parent = null
+ return ntype
+ end
+ error = eof
+
+ lexer = new Lexer(source)
+ var first = lexer.next
+ if first isa EOF then return first
+ var second = lexer.next
+ if second isa EOF and not second isa AError then
+ first.parent = null
+ return first
+ end
+
+ lexer = new InjectedLexer(source)
+ lexer.injected_before.add new TKwvar
+ lexer.injected_before.add new TId
+ lexer.injected_before.add new TAssign
+ lexer.injected_before.add new TOpar
+ lexer.injected_after.add new TCpar
+ tree = (new Parser(lexer)).parse
+ eof = tree.n_eof
+ if not eof isa AError then
+ var nexpr = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(AVardeclExpr).n_expr.as(AParExpr).n_expr
+ nexpr.parent = null
+ return nexpr
+ end
+ if eof.location > error.location then error = eof
+
+ lexer = new InjectedLexer(source)
+ lexer.injected_before.add new TKwdo
+ lexer.injected_before.add new TEol
+ lexer.injected_after.add new TEol
+ lexer.injected_after.add new TKwend
+ tree = (new Parser(lexer)).parse
+ eof = tree.n_eof
+ if not eof isa AError then
+ var nblock = tree.n_base.n_classdefs.first.n_propdefs.first.as(AMethPropdef).n_block.as(ABlockExpr).n_expr.first.as(ADoExpr).n_block.as(ABlockExpr)
+ nblock.n_kwend = null # drop injected token
+ nblock.parent = null
+ return nblock
+ end
+ if eof.location > error.location then error = eof
+
+ lexer = new Lexer(source)
+ tree = (new Parser(lexer)).parse
+ eof = tree.n_eof
+ if not eof isa AError then
+ return tree.n_base.as(not null)
+ end
+ if eof.location > error.location then error = eof
+
+ return error
+ end
+
+ # Parse the input of the user as something
+ fun interactive_parse(prompt: String): ANode