diff --git a/doc/SixtyPical.md b/doc/SixtyPical.md index e0e6624..0cdff8c 100644 --- a/doc/SixtyPical.md +++ b/doc/SixtyPical.md @@ -103,6 +103,15 @@ some memory locations causes those memory locations to be uninitialized after that routine is called. At the end of a routine, all memory locations listed as outputs must be initialised. +A routine can also be declared as "external", in which case its body need +not be defined but an absolute address must be given for where the routine +is located in memory. + + routine chrout + inputs a + trashes a + @ 65490 + Instructions ------------ @@ -291,12 +300,13 @@ Grammar Defn ::= "byte" NewIdent. Routine ::= "routine" NewIdent ["inputs" LocExprs] ["outputs" LocExprs] ["trashes" LocExprs] - Block. + (Block | "@" WordConst). LocExprs::= LocExpr {"," LocExpr}. - LocExpr ::= Register | Flag | Const | DefnIdent. + LocExpr ::= Register | Flag | LitByte | DefnIdent. Register::= "a" | "x" | "y". Flag ::= "c" | "z" | "n" | "v". - Const ::= "0" ... "255". + LitByte ::= "0" ... "255". + LitWord ::= "0" ... "65535". Block ::= "{" {Instr} "}". Instr ::= "ld" LocExpr "," LocExpr | "st" LocExpr "," LocExpr diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index ac59ac0..8f02e2d 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -30,7 +30,7 @@ class Scanner(object): self.token = None self.type = 'EOF' return - if self.scan_pattern(r'\,|\/|\{|\}', 'operator'): + if self.scan_pattern(r'\,|\@|\{|\}', 'operator'): return if self.scan_pattern(r'\d+', 'integer literal'): return @@ -119,10 +119,17 @@ class Parser(object): outputs = self.locexprs() if self.scanner.consume('trashes'): trashes = self.locexprs() - block = self.block() + if self.scanner.consume('@'): + self.scanner.check_type('integer literal') + block = None + addr = int(self.scanner.token) + self.scanner.scan() + else: + block = self.block() + addr = None return Routine( name=name, inputs=inputs, outputs=outputs, trashes=trashes, - block=block + block=block, addr=addr ) def locexprs(self): diff --git a/test.sh b/test.sh index 587e14a..00c9e71 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,7 @@ #!/bin/sh falderal --substring-error \ + tests/SixtyPical\ Syntax.md \ tests/SixtyPical\ Execution.md \ tests/SixtyPical\ Analysis.md \ tests/SixtyPical\ Compilation.md diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index 3fbdaf9..ab5ef14 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -29,3 +29,20 @@ Rudimentary program. | add a, 4 | } = 00c018690460 + +Call extern. + + | routine chrout + | inputs a + | trashes a + | @ 65490 + | + | routine main + | inputs a + | outputs a + | trashes c, z, n, v + | { + | ld a, 65 + | call chrout + | } + = 00c018690460 diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md new file mode 100644 index 0000000..b852528 --- /dev/null +++ b/tests/SixtyPical Syntax.md @@ -0,0 +1,41 @@ +Sixtypical Execution +==================== + +This is a test suite, written in [Falderal][] format, for the syntax of +the Sixtypical language, disgregarding execution, static analysis, etc. + +[Falderal]: http://catseye.tc/node/Falderal + + -> Functionality "Check syntax of Sixtypical program" is implemented by + -> shell command "bin/sixtypical %(test-body-file) && echo ok" + + -> Tests for functionality "Check syntax of Sixtypical program" + +Rudimentary program. + + | routine main { + | ld a, 0 + | add a, 1 + | } + = ok + +Syntax error + + | routine foo ( + | ld a, 0 + | add a, 1 + | ) + ? SyntaxError + +Extern routines + + | routine chrout + | inputs a + | trashes a + | @ 65490 + | + | routine chrin + | outputs a + | trashes x + | @ 65487 + = ok