diff --git a/ast.js b/ast.js deleted file mode 100644 index 93bba94..0000000 --- a/ast.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - Body(statements) { return { type: 'body', value: statements } }, - Link(identifier) { return { type: 'link', value: identifier } }, - Invocation(identifier, ...args) { return { type: 'invo', value: identifier, args } }, - Const(name, value) { return { type: 'const', value, name } }, - Int(n) { return { type: 'int', value: n } }, - String(s) { return { type: 'string', value: s } }, - Variable(name, value) { return { type: 'var', value, name } }, - VariableReference(name) { return { type: 'ref', value: name } }, -} \ No newline at end of file diff --git a/bytecode.json b/bytecode.json index 6593d15..4256d0e 100644 --- a/bytecode.json +++ b/bytecode.json @@ -1,21 +1,73 @@ [ - { - "type": "KEYWORD", - "value": "LINK" - }, - { - "type": "IDENTIFIER", - "value": "log1" - }, - { - "type": "NEWLINE" - }, - { - "type": "KEYWORD", - "value": "LINK" - }, - { - "type": "IDENTIFIER", - "value": "log2" - } + "", + "NEWLINE", + "link", + "log1", + "NEWLINE", + "link", + "log2", + "NEWLINE", + "", + "NEWLINE", + "", + "NEWLINE", + "", + "NEWLINE", + "link", + "log", + "NEWLINE", + "const", + "test", + "", + "=", + "", + "\"Hello\"", + "NEWLINE", + "const", + "", + "", + "", + "test2", + "", + "=", + "\"Hello2\"", + "NEWLINE", + "const", + "test3", + "", + "=", + "", + "'Hello'", + "NEWLINE", + "const", + "a", + "=", + "\"5\"", + "NEWLINE", + "log", + "(", + "test", + ")", + "", + "NEWLINE", + "log", + "(", + "\"World\"", + ")", + "", + "NEWLINE", + "log", + "(", + "\"Hello\n \"Wor(l)d\"\n\\o/\"", + ")", + "", + "NEWLINE", + "", + "NEWLINE", + "", + "NEWLINE", + "", + "NEWLINE", + "", + "NEWLINE" ] \ No newline at end of file diff --git a/disco.disco b/disco.disco index 3b0117d..cd84236 100644 --- a/disco.disco +++ b/disco.disco @@ -1,8 +1,4 @@ -link log1 -link log2 - - link log const test = "Hello" diff --git a/disco.js b/disco.js deleted file mode 100755 index 46e0775..0000000 --- a/disco.js +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env node - -const AST = require('./ast.js'); -const compile = require('./compiler.js'); - -const myProgram = AST.Body([ - AST.Variable('test1', AST.String('This String is Contained in a variable')), - AST.Variable('test2', AST.String('This is a second string in a variable')), - AST.Link('log'), - AST.Invocation('log', AST.String('hello')), - AST.Invocation('log', AST.String('world')), - AST.Invocation('log', AST.VariableReference('test1')), - AST.Invocation('log', AST.VariableReference('test2')), - AST.Invocation('log', AST.VariableReference('test1')), - AST.Invocation('log', AST.VariableReference('test2')), -]); - -const asmFile = compile(myProgram) -try { - require('fs').writeFileSync('out.asm', asmFile); - require('child_process').execSync('nasm -f elf64 out.asm -o out.o', { stdio: 'inherit' }); - require('child_process').execSync('ld out.o -o out', { stdio: 'inherit' }); - require('child_process').execSync('./out', { stdio: 'inherit' }); -} catch (e) { - process.exit(1); -} diff --git a/disco_test b/disco_test new file mode 100755 index 0000000..02fc381 Binary files /dev/null and b/disco_test differ diff --git a/disco_test.asm b/disco_test.asm new file mode 100644 index 0000000..091b005 --- /dev/null +++ b/disco_test.asm @@ -0,0 +1,51 @@ +section .data + VVQDDBDZ db 72,101,108,108,111,0 + EWXBIBSR db 72,101,108,108,111,50,0 + PJQDTHUC db 72,101,108,108,111,0 + ECIATSPU db 53,0 + GTZCFAMK db 87,111,114,108,100,0 + YDHYSXWS db 72,101,108,108,111,10,32,34,87,111,114,40,108,41,100,34,10,92,111,47,0 +section .text + global _start +_start: + push rbp + mov rbp, rsp + push VVQDDBDZ + push EWXBIBSR + push PJQDTHUC + push ECIATSPU + mov rdi, [rbp - 8] + call _log + mov rdi, GTZCFAMK + call _log + mov rdi, YDHYSXWS + call _log + mov rsp, rbp + pop rbp + mov rax, 60 + mov rdi, 0 + syscall +_log: + push rdi + mov rbx, 0 +_log_loop: + mov cl, [rdi] + cmp cl, 0 + je _log_loop_end + inc rdi + inc rbx + jmp _log_loop +_log_loop_end: + mov rdx, rbx + mov rax, 1 + mov rdi, 1 + pop rsi + syscall + push 10 + mov rax, 1 + mov rdi, 1 + mov rsi, rsp + mov rdx, 1 + syscall + pop rdi + ret \ No newline at end of file diff --git a/output.ansi b/output.ansi new file mode 100644 index 0000000..39ac3bc --- /dev/null +++ b/output.ansi @@ -0,0 +1,1125 @@ + +=== Tokenization === +($KeywordLink:0:0) ($Identifier:0:0) ($Newline:0:0) +($KeywordLink:0:0) ($Identifier:0:0) ($Newline:0:0) +($Newline:0:0) +($Newline:0:0) +($Newline:0:0) +($KeywordLink:0:0) ($Identifier:0:0) ($Newline:0:0) +($KeywordConst:0:0) ($Identifier:0:0) ($KeywordEquals:0:0) ($String:0:0) ($Newline:0:0) +($KeywordConst:0:0) ($Identifier:0:0) ($KeywordEquals:0:0) ($String:0:0) ($Newline:0:0) +($KeywordConst:0:0) ($Identifier:0:0) ($KeywordEquals:0:0) ($String:0:0) ($Newline:0:0) +($KeywordConst:0:0) ($Identifier:0:0) ($KeywordEquals:0:0) ($String:0:0) ($Newline:0:0) +($Identifier:0:0) ($KeywordLParen:0:0) ($Identifier:0:0) ($KeywordRParen:0:0) ($Newline:0:0) +($Identifier:0:0) ($KeywordLParen:0:0) ($String:0:0) ($KeywordRParen:0:0) ($Newline:0:0) +($Identifier:0:0) ($KeywordLParen:0:0) ($String:0:0) ($KeywordRParen:0:0) ($Newline:0:0) +($Newline:0:0) +($Newline:0:0) +($Newline:0:0) +($Newline:0:0) + +=== Parsing === +s0: $Program +$Program => • $Statement (0) +$Program => • $Statement $Program (0) +$Statement => • $Newline (0) +$LinkStatement => • $KeywordLink $Identifier (0) +$Statement => • $LinkStatement (0) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (0) +$Statement => • $VariableDeclaration (0) +$Expression => • $String (0) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (0) +$Expression => • $InvocationExpression (0) +$VariableReference => • $Identifier (0) +$Expression => • $VariableReference (0) +$Statement => • $Expression (0) +$Statement => • $Newline (0) +$LinkStatement => • $KeywordLink $Identifier (0) +$Statement => • $LinkStatement (0) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (0) +$Statement => • $VariableDeclaration (0) +$Expression => • $String (0) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (0) +$Expression => • $InvocationExpression (0) +$VariableReference => • $Identifier (0) +$Expression => • $VariableReference (0) +$Statement => • $Expression (0) + +s1: ($KeywordLink:0:0) +$LinkStatement => $KeywordLink • $Identifier (0) + +s2: ($Identifier:0:0) +$LinkStatement => $KeywordLink $Identifier • (0) +$Program => $Statement • (0) +$Statement => • $Newline (2) +$LinkStatement => • $KeywordLink $Identifier (2) +$Statement => • $LinkStatement (2) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (2) +$Statement => • $VariableDeclaration (2) +$Expression => • $String (2) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (2) +$Expression => • $InvocationExpression (2) +$VariableReference => • $Identifier (2) +$Expression => • $VariableReference (2) +$Statement => • $Expression (2) +$Program => • $Statement (2) +$Program => • $Statement $Program (2) +$Program => $Statement • $Program (0) +$Statement => $LinkStatement • (0) + +s3: ($Newline:0:0) +$Statement => $Newline • (2) +$Program => $Statement $Program • (0) +$Program => $Statement • (2) +$Statement => • $Newline (3) +$LinkStatement => • $KeywordLink $Identifier (3) +$Statement => • $LinkStatement (3) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (3) +$Statement => • $VariableDeclaration (3) +$Expression => • $String (3) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (3) +$Expression => • $InvocationExpression (3) +$VariableReference => • $Identifier (3) +$Expression => • $VariableReference (3) +$Statement => • $Expression (3) +$Program => • $Statement (3) +$Program => • $Statement $Program (3) +$Program => $Statement • $Program (2) + +s4: ($KeywordLink:0:0) +$LinkStatement => $KeywordLink • $Identifier (3) + +s5: ($Identifier:0:0) +$LinkStatement => $KeywordLink $Identifier • (3) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement • (3) +$Statement => • $Newline (5) +$LinkStatement => • $KeywordLink $Identifier (5) +$Statement => • $LinkStatement (5) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (5) +$Statement => • $VariableDeclaration (5) +$Expression => • $String (5) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (5) +$Expression => • $InvocationExpression (5) +$VariableReference => • $Identifier (5) +$Expression => • $VariableReference (5) +$Statement => • $Expression (5) +$Program => • $Statement (5) +$Program => • $Statement $Program (5) +$Program => $Statement • $Program (3) +$Statement => $LinkStatement • (3) + +s6: ($Newline:0:0) +$Statement => $Newline • (5) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement • (5) +$Statement => • $Newline (6) +$LinkStatement => • $KeywordLink $Identifier (6) +$Statement => • $LinkStatement (6) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (6) +$Statement => • $VariableDeclaration (6) +$Expression => • $String (6) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (6) +$Expression => • $InvocationExpression (6) +$VariableReference => • $Identifier (6) +$Expression => • $VariableReference (6) +$Statement => • $Expression (6) +$Program => • $Statement (6) +$Program => • $Statement $Program (6) +$Program => $Statement • $Program (5) + +s7: ($Newline:0:0) +$Statement => $Newline • (6) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement • (6) +$Statement => • $Newline (7) +$LinkStatement => • $KeywordLink $Identifier (7) +$Statement => • $LinkStatement (7) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (7) +$Statement => • $VariableDeclaration (7) +$Expression => • $String (7) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (7) +$Expression => • $InvocationExpression (7) +$VariableReference => • $Identifier (7) +$Expression => • $VariableReference (7) +$Statement => • $Expression (7) +$Program => • $Statement (7) +$Program => • $Statement $Program (7) +$Program => $Statement • $Program (6) + +s8: ($Newline:0:0) +$Statement => $Newline • (7) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement • (7) +$Statement => • $Newline (8) +$LinkStatement => • $KeywordLink $Identifier (8) +$Statement => • $LinkStatement (8) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (8) +$Statement => • $VariableDeclaration (8) +$Expression => • $String (8) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (8) +$Expression => • $InvocationExpression (8) +$VariableReference => • $Identifier (8) +$Expression => • $VariableReference (8) +$Statement => • $Expression (8) +$Program => • $Statement (8) +$Program => • $Statement $Program (8) +$Program => $Statement • $Program (7) + +s9: ($Newline:0:0) +$Statement => $Newline • (8) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement • (8) +$Statement => • $Newline (9) +$LinkStatement => • $KeywordLink $Identifier (9) +$Statement => • $LinkStatement (9) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (9) +$Statement => • $VariableDeclaration (9) +$Expression => • $String (9) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (9) +$Expression => • $InvocationExpression (9) +$VariableReference => • $Identifier (9) +$Expression => • $VariableReference (9) +$Statement => • $Expression (9) +$Program => • $Statement (9) +$Program => • $Statement $Program (9) +$Program => $Statement • $Program (8) + +s10: ($KeywordLink:0:0) +$LinkStatement => $KeywordLink • $Identifier (9) + +s11: ($Identifier:0:0) +$LinkStatement => $KeywordLink $Identifier • (9) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement • (9) +$Statement => • $Newline (11) +$LinkStatement => • $KeywordLink $Identifier (11) +$Statement => • $LinkStatement (11) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (11) +$Statement => • $VariableDeclaration (11) +$Expression => • $String (11) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (11) +$Expression => • $InvocationExpression (11) +$VariableReference => • $Identifier (11) +$Expression => • $VariableReference (11) +$Statement => • $Expression (11) +$Program => • $Statement (11) +$Program => • $Statement $Program (11) +$Program => $Statement • $Program (9) +$Statement => $LinkStatement • (9) + +s12: ($Newline:0:0) +$Statement => $Newline • (11) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement • (11) +$Statement => • $Newline (12) +$LinkStatement => • $KeywordLink $Identifier (12) +$Statement => • $LinkStatement (12) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (12) +$Statement => • $VariableDeclaration (12) +$Expression => • $String (12) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (12) +$Expression => • $InvocationExpression (12) +$VariableReference => • $Identifier (12) +$Expression => • $VariableReference (12) +$Statement => • $Expression (12) +$Program => • $Statement (12) +$Program => • $Statement $Program (12) +$Program => $Statement • $Program (11) + +s13: ($KeywordConst:0:0) +$VariableDeclaration => $KeywordConst • $Identifier $KeywordEquals $Expression (12) + +s14: ($Identifier:0:0) +$VariableDeclaration => $KeywordConst $Identifier • $KeywordEquals $Expression (12) + +s15: ($KeywordEquals:0:0) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals • $Expression (12) +$Expression => • $String (15) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (15) +$Expression => • $InvocationExpression (15) +$VariableReference => • $Identifier (15) +$Expression => • $VariableReference (15) + +s16: ($String:0:0) +$Expression => $String • (15) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement • (12) +$Statement => • $Newline (16) +$LinkStatement => • $KeywordLink $Identifier (16) +$Statement => • $LinkStatement (16) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (16) +$Statement => • $VariableDeclaration (16) +$Expression => • $String (16) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (16) +$Expression => • $InvocationExpression (16) +$VariableReference => • $Identifier (16) +$Expression => • $VariableReference (16) +$Statement => • $Expression (16) +$Program => • $Statement (16) +$Program => • $Statement $Program (16) +$Program => $Statement • $Program (12) +$Statement => $VariableDeclaration • (12) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals $Expression • (12) + +s17: ($Newline:0:0) +$Statement => $Newline • (16) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement • (16) +$Statement => • $Newline (17) +$LinkStatement => • $KeywordLink $Identifier (17) +$Statement => • $LinkStatement (17) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (17) +$Statement => • $VariableDeclaration (17) +$Expression => • $String (17) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (17) +$Expression => • $InvocationExpression (17) +$VariableReference => • $Identifier (17) +$Expression => • $VariableReference (17) +$Statement => • $Expression (17) +$Program => • $Statement (17) +$Program => • $Statement $Program (17) +$Program => $Statement • $Program (16) + +s18: ($KeywordConst:0:0) +$VariableDeclaration => $KeywordConst • $Identifier $KeywordEquals $Expression (17) + +s19: ($Identifier:0:0) +$VariableDeclaration => $KeywordConst $Identifier • $KeywordEquals $Expression (17) + +s20: ($KeywordEquals:0:0) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals • $Expression (17) +$Expression => • $String (20) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (20) +$Expression => • $InvocationExpression (20) +$VariableReference => • $Identifier (20) +$Expression => • $VariableReference (20) + +s21: ($String:0:0) +$Expression => $String • (20) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement • (17) +$Statement => • $Newline (21) +$LinkStatement => • $KeywordLink $Identifier (21) +$Statement => • $LinkStatement (21) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (21) +$Statement => • $VariableDeclaration (21) +$Expression => • $String (21) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (21) +$Expression => • $InvocationExpression (21) +$VariableReference => • $Identifier (21) +$Expression => • $VariableReference (21) +$Statement => • $Expression (21) +$Program => • $Statement (21) +$Program => • $Statement $Program (21) +$Program => $Statement • $Program (17) +$Statement => $VariableDeclaration • (17) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals $Expression • (17) + +s22: ($Newline:0:0) +$Statement => $Newline • (21) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement • (21) +$Statement => • $Newline (22) +$LinkStatement => • $KeywordLink $Identifier (22) +$Statement => • $LinkStatement (22) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (22) +$Statement => • $VariableDeclaration (22) +$Expression => • $String (22) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (22) +$Expression => • $InvocationExpression (22) +$VariableReference => • $Identifier (22) +$Expression => • $VariableReference (22) +$Statement => • $Expression (22) +$Program => • $Statement (22) +$Program => • $Statement $Program (22) +$Program => $Statement • $Program (21) + +s23: ($KeywordConst:0:0) +$VariableDeclaration => $KeywordConst • $Identifier $KeywordEquals $Expression (22) + +s24: ($Identifier:0:0) +$VariableDeclaration => $KeywordConst $Identifier • $KeywordEquals $Expression (22) + +s25: ($KeywordEquals:0:0) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals • $Expression (22) +$Expression => • $String (25) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (25) +$Expression => • $InvocationExpression (25) +$VariableReference => • $Identifier (25) +$Expression => • $VariableReference (25) + +s26: ($String:0:0) +$Expression => $String • (25) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement • (22) +$Statement => • $Newline (26) +$LinkStatement => • $KeywordLink $Identifier (26) +$Statement => • $LinkStatement (26) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (26) +$Statement => • $VariableDeclaration (26) +$Expression => • $String (26) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (26) +$Expression => • $InvocationExpression (26) +$VariableReference => • $Identifier (26) +$Expression => • $VariableReference (26) +$Statement => • $Expression (26) +$Program => • $Statement (26) +$Program => • $Statement $Program (26) +$Program => $Statement • $Program (22) +$Statement => $VariableDeclaration • (22) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals $Expression • (22) + +s27: ($Newline:0:0) +$Statement => $Newline • (26) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement • (26) +$Statement => • $Newline (27) +$LinkStatement => • $KeywordLink $Identifier (27) +$Statement => • $LinkStatement (27) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (27) +$Statement => • $VariableDeclaration (27) +$Expression => • $String (27) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (27) +$Expression => • $InvocationExpression (27) +$VariableReference => • $Identifier (27) +$Expression => • $VariableReference (27) +$Statement => • $Expression (27) +$Program => • $Statement (27) +$Program => • $Statement $Program (27) +$Program => $Statement • $Program (26) + +s28: ($KeywordConst:0:0) +$VariableDeclaration => $KeywordConst • $Identifier $KeywordEquals $Expression (27) + +s29: ($Identifier:0:0) +$VariableDeclaration => $KeywordConst $Identifier • $KeywordEquals $Expression (27) + +s30: ($KeywordEquals:0:0) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals • $Expression (27) +$Expression => • $String (30) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (30) +$Expression => • $InvocationExpression (30) +$VariableReference => • $Identifier (30) +$Expression => • $VariableReference (30) + +s31: ($String:0:0) +$Expression => $String • (30) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement • (27) +$Statement => • $Newline (31) +$LinkStatement => • $KeywordLink $Identifier (31) +$Statement => • $LinkStatement (31) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (31) +$Statement => • $VariableDeclaration (31) +$Expression => • $String (31) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (31) +$Expression => • $InvocationExpression (31) +$VariableReference => • $Identifier (31) +$Expression => • $VariableReference (31) +$Statement => • $Expression (31) +$Program => • $Statement (31) +$Program => • $Statement $Program (31) +$Program => $Statement • $Program (27) +$Statement => $VariableDeclaration • (27) +$VariableDeclaration => $KeywordConst $Identifier $KeywordEquals $Expression • (27) + +s32: ($Newline:0:0) +$Statement => $Newline • (31) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement • (31) +$Statement => • $Newline (32) +$LinkStatement => • $KeywordLink $Identifier (32) +$Statement => • $LinkStatement (32) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (32) +$Statement => • $VariableDeclaration (32) +$Expression => • $String (32) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (32) +$Expression => • $InvocationExpression (32) +$VariableReference => • $Identifier (32) +$Expression => • $VariableReference (32) +$Statement => • $Expression (32) +$Program => • $Statement (32) +$Program => • $Statement $Program (32) +$Program => $Statement • $Program (31) + +s33: ($Identifier:0:0) +$InvocationExpression => $Identifier • $KeywordLParen $Expression $KeywordRParen (32) +$VariableReference => $Identifier • (32) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement • (32) +$Statement => • $Newline (33) +$LinkStatement => • $KeywordLink $Identifier (33) +$Statement => • $LinkStatement (33) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (33) +$Statement => • $VariableDeclaration (33) +$Expression => • $String (33) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (33) +$Expression => • $InvocationExpression (33) +$VariableReference => • $Identifier (33) +$Expression => • $VariableReference (33) +$Statement => • $Expression (33) +$Program => • $Statement (33) +$Program => • $Statement $Program (33) +$Program => $Statement • $Program (32) +$Statement => $Expression • (32) +$Expression => $VariableReference • (32) + +s34: ($KeywordLParen:0:0) +$InvocationExpression => $Identifier $KeywordLParen • $Expression $KeywordRParen (32) +$Expression => • $String (34) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (34) +$Expression => • $InvocationExpression (34) +$VariableReference => • $Identifier (34) +$Expression => • $VariableReference (34) + +s35: ($Identifier:0:0) +$InvocationExpression => $Identifier • $KeywordLParen $Expression $KeywordRParen (34) +$VariableReference => $Identifier • (34) +$InvocationExpression => $Identifier $KeywordLParen $Expression • $KeywordRParen (32) +$Expression => $VariableReference • (34) + +s36: ($KeywordRParen:0:0) +$InvocationExpression => $Identifier $KeywordLParen $Expression $KeywordRParen • (32) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement • (32) +$Statement => • $Newline (36) +$LinkStatement => • $KeywordLink $Identifier (36) +$Statement => • $LinkStatement (36) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (36) +$Statement => • $VariableDeclaration (36) +$Expression => • $String (36) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (36) +$Expression => • $InvocationExpression (36) +$VariableReference => • $Identifier (36) +$Expression => • $VariableReference (36) +$Statement => • $Expression (36) +$Program => • $Statement (36) +$Program => • $Statement $Program (36) +$Program => $Statement • $Program (32) +$Statement => $Expression • (32) +$Expression => $InvocationExpression • (32) + +s37: ($Newline:0:0) +$Statement => $Newline • (36) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement • (36) +$Statement => • $Newline (37) +$LinkStatement => • $KeywordLink $Identifier (37) +$Statement => • $LinkStatement (37) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (37) +$Statement => • $VariableDeclaration (37) +$Expression => • $String (37) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (37) +$Expression => • $InvocationExpression (37) +$VariableReference => • $Identifier (37) +$Expression => • $VariableReference (37) +$Statement => • $Expression (37) +$Program => • $Statement (37) +$Program => • $Statement $Program (37) +$Program => $Statement • $Program (36) + +s38: ($Identifier:0:0) +$InvocationExpression => $Identifier • $KeywordLParen $Expression $KeywordRParen (37) +$VariableReference => $Identifier • (37) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement • (37) +$Statement => • $Newline (38) +$LinkStatement => • $KeywordLink $Identifier (38) +$Statement => • $LinkStatement (38) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (38) +$Statement => • $VariableDeclaration (38) +$Expression => • $String (38) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (38) +$Expression => • $InvocationExpression (38) +$VariableReference => • $Identifier (38) +$Expression => • $VariableReference (38) +$Statement => • $Expression (38) +$Program => • $Statement (38) +$Program => • $Statement $Program (38) +$Program => $Statement • $Program (37) +$Statement => $Expression • (37) +$Expression => $VariableReference • (37) + +s39: ($KeywordLParen:0:0) +$InvocationExpression => $Identifier $KeywordLParen • $Expression $KeywordRParen (37) +$Expression => • $String (39) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (39) +$Expression => • $InvocationExpression (39) +$VariableReference => • $Identifier (39) +$Expression => • $VariableReference (39) + +s40: ($String:0:0) +$Expression => $String • (39) +$InvocationExpression => $Identifier $KeywordLParen $Expression • $KeywordRParen (37) + +s41: ($KeywordRParen:0:0) +$InvocationExpression => $Identifier $KeywordLParen $Expression $KeywordRParen • (37) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement • (37) +$Statement => • $Newline (41) +$LinkStatement => • $KeywordLink $Identifier (41) +$Statement => • $LinkStatement (41) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (41) +$Statement => • $VariableDeclaration (41) +$Expression => • $String (41) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (41) +$Expression => • $InvocationExpression (41) +$VariableReference => • $Identifier (41) +$Expression => • $VariableReference (41) +$Statement => • $Expression (41) +$Program => • $Statement (41) +$Program => • $Statement $Program (41) +$Program => $Statement • $Program (37) +$Statement => $Expression • (37) +$Expression => $InvocationExpression • (37) + +s42: ($Newline:0:0) +$Statement => $Newline • (41) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement • (41) +$Statement => • $Newline (42) +$LinkStatement => • $KeywordLink $Identifier (42) +$Statement => • $LinkStatement (42) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (42) +$Statement => • $VariableDeclaration (42) +$Expression => • $String (42) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (42) +$Expression => • $InvocationExpression (42) +$VariableReference => • $Identifier (42) +$Expression => • $VariableReference (42) +$Statement => • $Expression (42) +$Program => • $Statement (42) +$Program => • $Statement $Program (42) +$Program => $Statement • $Program (41) + +s43: ($Identifier:0:0) +$InvocationExpression => $Identifier • $KeywordLParen $Expression $KeywordRParen (42) +$VariableReference => $Identifier • (42) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement • (42) +$Statement => • $Newline (43) +$LinkStatement => • $KeywordLink $Identifier (43) +$Statement => • $LinkStatement (43) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (43) +$Statement => • $VariableDeclaration (43) +$Expression => • $String (43) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (43) +$Expression => • $InvocationExpression (43) +$VariableReference => • $Identifier (43) +$Expression => • $VariableReference (43) +$Statement => • $Expression (43) +$Program => • $Statement (43) +$Program => • $Statement $Program (43) +$Program => $Statement • $Program (42) +$Statement => $Expression • (42) +$Expression => $VariableReference • (42) + +s44: ($KeywordLParen:0:0) +$InvocationExpression => $Identifier $KeywordLParen • $Expression $KeywordRParen (42) +$Expression => • $String (44) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (44) +$Expression => • $InvocationExpression (44) +$VariableReference => • $Identifier (44) +$Expression => • $VariableReference (44) + +s45: ($String:0:0) +$Expression => $String • (44) +$InvocationExpression => $Identifier $KeywordLParen $Expression • $KeywordRParen (42) + +s46: ($KeywordRParen:0:0) +$InvocationExpression => $Identifier $KeywordLParen $Expression $KeywordRParen • (42) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement • (42) +$Statement => • $Newline (46) +$LinkStatement => • $KeywordLink $Identifier (46) +$Statement => • $LinkStatement (46) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (46) +$Statement => • $VariableDeclaration (46) +$Expression => • $String (46) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (46) +$Expression => • $InvocationExpression (46) +$VariableReference => • $Identifier (46) +$Expression => • $VariableReference (46) +$Statement => • $Expression (46) +$Program => • $Statement (46) +$Program => • $Statement $Program (46) +$Program => $Statement • $Program (42) +$Statement => $Expression • (42) +$Expression => $InvocationExpression • (42) + +s47: ($Newline:0:0) +$Statement => $Newline • (46) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement $Program • (42) +$Program => $Statement • (46) +$Statement => • $Newline (47) +$LinkStatement => • $KeywordLink $Identifier (47) +$Statement => • $LinkStatement (47) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (47) +$Statement => • $VariableDeclaration (47) +$Expression => • $String (47) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (47) +$Expression => • $InvocationExpression (47) +$VariableReference => • $Identifier (47) +$Expression => • $VariableReference (47) +$Statement => • $Expression (47) +$Program => • $Statement (47) +$Program => • $Statement $Program (47) +$Program => $Statement • $Program (46) + +s48: ($Newline:0:0) +$Statement => $Newline • (47) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement $Program • (42) +$Program => $Statement $Program • (46) +$Program => $Statement • (47) +$Statement => • $Newline (48) +$LinkStatement => • $KeywordLink $Identifier (48) +$Statement => • $LinkStatement (48) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (48) +$Statement => • $VariableDeclaration (48) +$Expression => • $String (48) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (48) +$Expression => • $InvocationExpression (48) +$VariableReference => • $Identifier (48) +$Expression => • $VariableReference (48) +$Statement => • $Expression (48) +$Program => • $Statement (48) +$Program => • $Statement $Program (48) +$Program => $Statement • $Program (47) + +s49: ($Newline:0:0) +$Statement => $Newline • (48) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement $Program • (42) +$Program => $Statement $Program • (46) +$Program => $Statement $Program • (47) +$Program => $Statement • (48) +$Statement => • $Newline (49) +$LinkStatement => • $KeywordLink $Identifier (49) +$Statement => • $LinkStatement (49) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (49) +$Statement => • $VariableDeclaration (49) +$Expression => • $String (49) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (49) +$Expression => • $InvocationExpression (49) +$VariableReference => • $Identifier (49) +$Expression => • $VariableReference (49) +$Statement => • $Expression (49) +$Program => • $Statement (49) +$Program => • $Statement $Program (49) +$Program => $Statement • $Program (48) + +s50: ($Newline:0:0) +$Statement => $Newline • (49) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement $Program • (42) +$Program => $Statement $Program • (46) +$Program => $Statement $Program • (47) +$Program => $Statement $Program • (48) +$Program => $Statement • (49) +$Statement => • $Newline (50) +$LinkStatement => • $KeywordLink $Identifier (50) +$Statement => • $LinkStatement (50) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (50) +$Statement => • $VariableDeclaration (50) +$Expression => • $String (50) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (50) +$Expression => • $InvocationExpression (50) +$VariableReference => • $Identifier (50) +$Expression => • $VariableReference (50) +$Statement => • $Expression (50) +$Program => • $Statement (50) +$Program => • $Statement $Program (50) +$Program => $Statement • $Program (49) + +s51: ($Newline:0:0) +$Statement => $Newline • (50) +$Program => $Statement $Program • (0) +$Program => $Statement $Program • (2) +$Program => $Statement $Program • (3) +$Program => $Statement $Program • (5) +$Program => $Statement $Program • (6) +$Program => $Statement $Program • (7) +$Program => $Statement $Program • (8) +$Program => $Statement $Program • (9) +$Program => $Statement $Program • (11) +$Program => $Statement $Program • (12) +$Program => $Statement $Program • (16) +$Program => $Statement $Program • (17) +$Program => $Statement $Program • (21) +$Program => $Statement $Program • (22) +$Program => $Statement $Program • (26) +$Program => $Statement $Program • (27) +$Program => $Statement $Program • (31) +$Program => $Statement $Program • (32) +$Program => $Statement $Program • (36) +$Program => $Statement $Program • (37) +$Program => $Statement $Program • (41) +$Program => $Statement $Program • (42) +$Program => $Statement $Program • (46) +$Program => $Statement $Program • (47) +$Program => $Statement $Program • (48) +$Program => $Statement $Program • (49) +$Program => $Statement • (50) +$Statement => • $Newline (51) +$LinkStatement => • $KeywordLink $Identifier (51) +$Statement => • $LinkStatement (51) +$VariableDeclaration => • $KeywordConst $Identifier $KeywordEquals $Expression (51) +$Statement => • $VariableDeclaration (51) +$Expression => • $String (51) +$InvocationExpression => • $Identifier $KeywordLParen $Expression $KeywordRParen (51) +$Expression => • $InvocationExpression (51) +$VariableReference => • $Identifier (51) +$Expression => • $VariableReference (51) +$Statement => • $Expression (51) +$Program => • $Statement (51) +$Program => • $Statement $Program (51) +$Program => $Statement • $Program (50) + +[ true ] diff --git a/package.json b/package.json index 5246f7e..053b449 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "dev": "yarn build && yarn start" }, "dependencies": { + "@types/node": "^17.0.21", "chalk": "3", "typescript": "^4.6.2" } diff --git a/src/ast.ts b/src/ast.ts new file mode 100644 index 0000000..6211d28 --- /dev/null +++ b/src/ast.ts @@ -0,0 +1,15 @@ +export const AST = { + Body(statements: any[]): any { + return { + type: 'body', + value: statements + } + }, + Link(identifier: any): any { return { type: 'link', value: identifier } }, + Invocation(identifier: any, ...args: any[]): any { return { type: 'invo', value: identifier, args } }, + Const(name: any, value: any): any { return { type: 'const', value, name } }, + Int(n: any): any { return { type: 'int', value: n } }, + String(s: any): any { return { type: 'string', value: s } }, + Variable(name: any, value: any): any { return { type: 'var', value, name } }, + VariableReference(name: any): any { return { type: 'ref', value: name } }, +} \ No newline at end of file diff --git a/compiler.js b/src/compiler.ts similarity index 95% rename from compiler.js rename to src/compiler.ts index 7467b14..b121f96 100644 --- a/compiler.js +++ b/src/compiler.ts @@ -5,8 +5,8 @@ const rname = () => (new Array(8).fill('')) ]).join(''); const linkables = { - log: require('./linkables/log.js'), - exit: require('./linkables/exit.js') + log: require('../linkables/log.js'), + exit: require('../linkables/exit.js') }; const callingConvention = { @@ -109,7 +109,7 @@ function compileStatement(item) { compileInvocation(item.value, ...item.args); break; } - case 'var': { + case 'const': { compileVariable(item.name, item.value); break; } @@ -119,11 +119,9 @@ function compileStatement(item) { } } -function compile(tree) { +export function compile(tree) { for(const item of tree.value) { compileStatement(item); } return sections.data() + '\n' + sections.text(); -} - -module.exports = compile; \ No newline at end of file +} \ No newline at end of file diff --git a/src/disco.ts b/src/disco.ts new file mode 100755 index 0000000..13fc55f --- /dev/null +++ b/src/disco.ts @@ -0,0 +1,51 @@ +#!/usr/bin/env node + +// const AST = require('../ast.js'); +// const compile = require('../compiler.js'); + +import { readFileSync } from "fs"; +import { compile } from "./compiler"; +import grammar, { $Newline } from "./grammar"; +import { tokenize } from "./tokenizer"; + +console.log(); +console.log('=== Original ==='); +const fileContents = readFileSync('./disco.disco').toString('utf-8'); +console.log(fileContents) + +console.log('=== Tokenization ==='); +const tokens = tokenize(fileContents); +for(const token of tokens) { + process.stdout.write(token.toString() + ' '); + if(token instanceof $Newline) console.log(); +} + +console.log(); +console.log('=== Parsing ==='); + +const ast = grammar.solveFor(tokens)[0]; + +console.log(); +console.log('=== AST ==='); +console.dir(ast, { + depth: Infinity +}); + +const asmFile = compile(ast) + +try { + console.log(); + console.log('=== ASM ==='); + console.log(asmFile); + require('fs').writeFileSync('disco_test.asm', asmFile); + + console.log(); + console.log('=== nasm ==='); + require('child_process').execSync('nasm -f elf64 disco_test.asm -o disco_test.o', { stdio: 'inherit' }); + console.log('=== ld ==='); + require('child_process').execSync('ld disco_test.o -o disco_test', { stdio: 'inherit' }); + console.log('=== execute ==='); + require('child_process').execSync('./disco_test', { stdio: 'inherit' }); +} catch (e) { + process.exit(1); +} diff --git a/src/createAST.ts b/src/earley.ts similarity index 83% rename from src/createAST.ts rename to src/earley.ts index 337f73f..3c42a45 100644 --- a/src/createAST.ts +++ b/src/earley.ts @@ -3,7 +3,7 @@ import * as chalk from 'chalk'; const rgb2ansi = (r: number, g: number, b: number) => r * 36 + g * 6 + b + 16 const ansi = (r: number, g = r, b = r) => chalk.ansi256(rgb2ansi(r, g, b)); -abstract class Token { +export abstract class Token { l: number; c: number; static terminal: boolean; @@ -31,8 +31,9 @@ abstract class Token { ansi(2)(')') } } -class NonTerminal extends Token { static terminal: false = false }; -class Terminal extends Token { static terminal: true = true }; + +export class NonTerminal extends Token { static terminal: false = false }; +export class Terminal extends Token { static terminal: true = true }; function isTerminal(tokenClass: TokenClass): tokenClass is TerminalTokenClass { return tokenClass.terminal; @@ -46,14 +47,6 @@ type TerminalTokenClass = { new(...args: any[]) : Terminal, terminal: true } type NonTerminalTokenClass = { new(...args: any[]) : NonTerminal, terminal: false } type TokenClass = TerminalTokenClass | NonTerminalTokenClass; -// class Identifier extends Token { constructor(l, c, value) { super(l, c); this.value = value; } } -class $Number extends Terminal { value: string; constructor(l: number, c: number, value: string) { super(l, c); this.value = value; } } -class $Plus extends Terminal { } -class $Times extends Terminal { } -class $Term extends NonTerminal { } -class $Poop extends NonTerminal { } -class $Addition extends NonTerminal { } - function getTokenClassFromToken(token: Token): TokenClass { return token.constructor as TokenClass; } @@ -88,13 +81,13 @@ class TimeMachine { } } -interface Production { +export interface Production { left: TokenClass; right: TokenClass[]; - // resolver: (...args: any[]) => any; + resolver?: (...args: any[]) => any; } -class Grammar { +export class Grammar { private productions: Production[]; private startingSymbol: NonTerminalTokenClass; @@ -108,16 +101,17 @@ class Grammar { const possibleStartingProductions = getProductionsForTokenClass(this.productions, this.startingSymbol) for(const production of possibleStartingProductions) { - state.current.partialMatches.push(new PartialMatch(production, 0, state.currentIndex)); + state.current.partialMatches.push(new PartialMatch(production, 0, state.currentIndex, [])); } // expand all non terminals here again const expand = (partial: PartialMatch) => { if(partial.complete) { + const resolvedData = partial.resolve(); const pastPartials = state.stateByIndex(partial.source).partialMatches; for(const pastPartial of pastPartials) { if(pastPartial.nextTokenClass === partial.production.left) { - const newPartial = pastPartial.getAdvancedCopy(); + const newPartial = pastPartial.getAdvancedCopy(resolvedData); expand(newPartial); state.current.partialMatches.push(newPartial); } @@ -128,7 +122,7 @@ class Grammar { if(isTerminal(nextTokenClass)) return; const possibleProductions = getProductionsForTokenClass(this.productions, nextTokenClass); for(const production of possibleProductions) { - const partialMatch = new PartialMatch(production, 0, state.currentIndex); + const partialMatch = new PartialMatch(production, 0, state.currentIndex, []); expand(partialMatch); state.current.partialMatches.push(partialMatch) } @@ -139,7 +133,7 @@ class Grammar { // expand all non terminals here console.log(ansi(3, 3, 0)('s') + ansi(4, 4, 0)(state.currentIndex) + ': ' + this.startingSymbol.toString()); - console.log(state.current.toString(), '\n\n') + console.log(state.current.toString(), '\n') for(const token of tokens) { state.newState(); @@ -149,7 +143,7 @@ class Grammar { if(partialMatch.complete) continue; // if our current token falls in line with what we need, then yeah, lets do it. if(token instanceof partialMatch.nextTokenClass) { - state.current.partialMatches.push(partialMatch.getAdvancedCopy()); + state.current.partialMatches.push(partialMatch.getAdvancedCopy(token)); } } @@ -158,8 +152,18 @@ class Grammar { state.current.partialMatches.forEach(expand); state.current.deduplicate() - console.log(state.current.toString(), '\n\n') + console.log(state.current.toString(), '\n') } + + const completedResolutions = []; + + for(const partial of state.current.partialMatches) { + if(partial.complete && partial.source === 0) { + completedResolutions.push(partial.resolve()); + } + } + + return completedResolutions; } } @@ -182,10 +186,12 @@ class PartialMatch { readonly production: Production; readonly progress: number = 0; readonly source: number = 0; - constructor(production: Production, completion: number, source: number) { + readonly resolvedData = []; + constructor(production: Production, completion: number, source: number, resolvedData: any[]) { this.production = production; this.progress = completion; this.source = source; + this.resolvedData = resolvedData; } get complete() { return this.production.right.length === this.progress; @@ -197,8 +203,15 @@ class PartialMatch { // if() // return getFirstTerminalsForTokenClass // } - getAdvancedCopy() { - return new PartialMatch(this.production, this.progress + 1, this.source); + resolve() { + if('resolver' in this.production) { + return this.production.resolver(...this.resolvedData); + } else { + return this.resolvedData; + } + } + getAdvancedCopy(resolvedData: any) { + return new PartialMatch(this.production, this.progress + 1, this.source, [...this.resolvedData, resolvedData]); } toString() { const rightSide = []; @@ -208,7 +221,7 @@ class PartialMatch { rightSide.push(this.production.right[i].toString()) } if(this.complete) addDot(); - return this.production.left.toString() + ansi(2, 2, 2)(' => ') + rightSide.join(' ') + ansi(2, 2, 2)(' (' + this.source + ')') + return this.production.left.toString() + ansi(2, 2, 2)(' => ') + rightSide.join(' ') + ansi(2, 2, 2)(' (' + this.source + ')'); } } @@ -237,28 +250,5 @@ class SingleEarleyState { } } -const tokens: Token[] = [ - new $Number(1, 1, '45'), - new $Plus(1, 3), - new $Number(1, 1, '45'), - new $Times(1, 3), - new $Number(1, 1, '45'), - new $Plus(1, 3), - new $Number(1, 1, '45'), -] -const ps: Production[] = [ - { - left: $Term, right: [$Addition, $Times, $Addition] - }, - { - left: $Addition, right: [$Number, $Plus, $Number] - }, -] - -const grammar = new Grammar(ps, $Term); - -console.log(grammar.solveFor(tokens)); - -// console.log(getFirstTerminalsForTokenClass(ps, $Term)) diff --git a/src/grammar.ts b/src/grammar.ts new file mode 100644 index 0000000..e16a213 --- /dev/null +++ b/src/grammar.ts @@ -0,0 +1,63 @@ +import { Grammar, NonTerminal, Production, Terminal, Token } from "./earley"; +import { AST } from './ast'; + +export class $KeywordLink extends Terminal { } +export class $KeywordEquals extends Terminal { } +export class $KeywordLParen extends Terminal { } +export class $KeywordRParen extends Terminal { } +export class $KeywordConst extends Terminal { } + +export class $String extends Terminal { + value: string; + constructor(l: number, c: number, value: string) { + super(l, c); + this.value = value; + } +} + +export class $Identifier extends Terminal { + value: string; + constructor(l: number, c: number, value: string) { + super(l, c); + this.value = value; + } +} + +export class $Newline extends Terminal { } + +export class $Program extends NonTerminal { } +export class $Statement extends NonTerminal { } +export class $LinkStatement extends NonTerminal { } +export class $VariableDeclaration extends NonTerminal { } +export class $Expression extends NonTerminal { } +export class $InvocationExpression extends NonTerminal { } +export class $VariableReference extends NonTerminal { } + +const ps: Production[] = [ + { left: $Program, right: [$Statement], resolver: (s) => !!s ? AST.Body([s]) : AST.Body([]) }, + { left: $Program, right: [$Statement, $Program], resolver: (s, ss) => !!s ? AST.Body([s, ...ss.value]) : ss}, + + { left: $Statement, right: [$Newline], resolver: () => false }, + { left: $Statement, right: [$LinkStatement], resolver: a => a }, + { left: $Statement, right: [$VariableDeclaration], resolver: a => a }, + { left: $Statement, right: [$Expression], resolver: a => a }, + + { left: $Expression, right: [$String], resolver: (s: $String) => AST.String(s.value) }, + { left: $Expression, right: [$InvocationExpression], resolver: a => a }, + { left: $Expression, right: [$VariableReference], resolver: a => a }, + + { left: $VariableReference, right: [$Identifier], resolver: (identifier: $Identifier) => AST.VariableReference(identifier.value) }, + + { left: $InvocationExpression, right: [$Identifier, $KeywordLParen, $Expression, $KeywordRParen], + resolver: (identifier: $Identifier, _, arg: any, __) => AST.Invocation(identifier.value, arg) }, + + { left: $VariableDeclaration, right: [$KeywordConst, $Identifier, $KeywordEquals, $Expression], + resolver: (_, identifier: $Identifier, __, value: any) => AST.Const(identifier.value, value) }, + + { left: $LinkStatement, right: [$KeywordLink, $Identifier], resolver: (_, identifier: $Identifier) => AST.Link(identifier.value) }, + +] + +const grammar = new Grammar(ps, $Program); + +export default grammar; \ No newline at end of file diff --git a/tokenizer.js b/src/tokenizer.ts similarity index 54% rename from tokenizer.js rename to src/tokenizer.ts index 7dd9676..09cfa74 100644 --- a/tokenizer.js +++ b/src/tokenizer.ts @@ -1,21 +1,17 @@ -const chalk = require('chalk'); +import * as chalk from 'chalk'; +import { readFileSync, writeFileSync } from 'fs'; +import { $Identifier, $KeywordConst, $KeywordEquals, $KeywordLink, $KeywordLParen, $KeywordRParen, $Newline, $String } from './grammar'; -// const keywords = new Map([ -// ['=', 'EQUALS'], -// ['(', 'LPAREN'], -// [')', 'RPAREN'], -// ['link', 'LINK'], -// ['const', 'CONST'], -// ]); -// const Tokens = { -// Keyword(str) { return { type: 'KEYWORD', value: keywords.get(str) } }, -// Newline() { return { type: 'NEWLINE' } }, -// Identifier(str) { return { type: 'IDENTIFIER', value: str } }, -// String(str) { return { type: 'STRING', value: str } } -// } +const keywords = new Map([ + ['=', $KeywordEquals], + ['(', $KeywordLParen], + [')', $KeywordRParen], + ['link', $KeywordLink], + ['const', $KeywordConst], +]); -function tokenize(string) { +export function tokenize(string) { let inString = false; let escaping = false; let tokens = []; @@ -25,26 +21,26 @@ function tokenize(string) { // const newline = () => (col = 1, line ++); // const nextColumn = () => line ++; const resetToken = () => token = ''; - const addToken = (_token) => { - tokens.push(_token ?? token); - resetToken(); + const addToken = (_token?) => { + if(_token) { + token = _token; + } + if(token.trim() !== '') { + if(keywords.has(token)) { + const kwTokenClass = keywords.get(token); + tokens.push(new kwTokenClass(0, 0)); + } else if (isStringDelim(token[0])) + tokens.push(new $String(0, 0, token.substring(1, token.length - 1))); + else if (token === 'NEWLINE') + tokens.push(new $Newline(0, 0)) + else + tokens.push(new $Identifier(0, 0, token)); + resetToken(); + } } - // // let _line = line; - // // let _col = col; - // if(_token) { - // token = _token; - // } - // if(token.trim() !== '') { - // if(keywords.has(token)) - // tokens.push(Tokens.Keyword(token)); - // else if (isStringDelim(token[0])) - // tokens.push(Tokens.String(token)); - // else if (token === 'NEWLINE') - // tokens.push(Tokens.Newline()) - // else - // tokens.push(Tokens.Identifier(token)); - // resetToken(); - // } + // let _line = line; + // let _col = col; + const isWhitespace = (char) => [' ', '\n', '\t', '\r'].includes(char); const isNewline = (char) => char === '\n'; const isSingleCharToken = (char) => ['(', ')', '='].includes(char); @@ -87,11 +83,3 @@ function tokenize(string) { return tokens; } - -module.exports = tokenize; - -const tokens = tokenize(require('fs').readFileSync('disco.disco').toString('utf-8')); - - -require('fs').writeFileSync('bytecode.json', JSON.stringify(tokens, null, 2)) - diff --git a/tsconfig.json b/tsconfig.json index a17dd70..63c0c64 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "target": "ESNext", "strictFunctionTypes": true, "sourceMap": true, - "outDir": "out" + "outDir": "out", + "declaration": true }, "include": [ "src/**/*.ts" diff --git a/yarn.lock b/yarn.lock index 5f9b686..a7e2ff7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@types/node@^17.0.21": + version "17.0.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644" + integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== + ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"