diff --git a/HISTORY.markdown b/HISTORY.markdown index 3876487..d799267 100644 --- a/HISTORY.markdown +++ b/HISTORY.markdown @@ -1,6 +1,11 @@ History of SixtyPical ===================== +0.7-PRE +------- + +* User-defined `byte` locations can be given an initial value. + 0.6 --- diff --git a/README.markdown b/README.markdown index 3819d22..280a12c 100644 --- a/README.markdown +++ b/README.markdown @@ -44,8 +44,6 @@ TODO For 0.7: -* initialized `byte` memory locations -* initialized `byte table` memory locations * `word` type. * `word table` type. @@ -60,6 +58,7 @@ For 0.9 At some point... +* initialized `byte table` memory locations * always analyze before executing or compiling, unless told not to * `trash` instruction. * `interrupt` routines. diff --git a/doc/SixtyPical.md b/doc/SixtyPical.md index b738325..4759d94 100644 --- a/doc/SixtyPical.md +++ b/doc/SixtyPical.md @@ -86,8 +86,7 @@ An address in memory may be given explicitly on a user-defined memory location. Or, a user-defined memory location may be given an initial value. But in this case, an explicit address in memory cannot be given. - byte pos = 0 - byte table scores = [1, 3, 8, 17, 26, 100] + byte pos : 0 A user-defined vector memory location is decorated with READS and WRITES lists like a routine (see below), and it may only hold addresses of routines which diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 6123974..067d6b2 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -57,8 +57,16 @@ class Compiler(object): self.emitter.resolve_label(label) self.emitter.emit(JMP(Indirect(self.labels[location.name]))) + # initialized data for defn in program.defns: - if defn.addr is None: + if defn.initial is not None: + label = self.labels[defn.name] + self.emitter.resolve_label(label) + self.emitter.emit(Byte(defn.initial)) + + # uninitialized, "BSS" data + for defn in program.defns: + if defn.initial is None and defn.addr is None: label = self.labels[defn.name] self.emitter.resolve_bss_label(label) diff --git a/src/sixtypical/evaluator.py b/src/sixtypical/evaluator.py index 90b9513..839790d 100644 --- a/src/sixtypical/evaluator.py +++ b/src/sixtypical/evaluator.py @@ -37,10 +37,16 @@ class Evaluator(object): for ref in (REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C): context.set(ref, 0) main = None + + for defn in program.defns: + if defn.initial is not None: + context.set(defn.location, defn.initial) + for routine in program.routines: context.set(routine.location, routine) if routine.name == 'main': main = routine + self.eval_routine(main, context) return context diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index 2323213..403f9aa 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -36,7 +36,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 @@ -140,13 +140,24 @@ class Parser(object): elif inputs or outputs or trashes: raise SyntaxError("Cannot apply constraints to non-vector type") + initial = None + if self.scanner.consume(':'): + self.scanner.check_type('integer literal') + initial = int(self.scanner.token) + self.scanner.scan() + addr = None if self.scanner.consume('@'): self.scanner.check_type('integer literal') addr = int(self.scanner.token) self.scanner.scan() + + if initial is not None and addr is not None: + raise SyntaxError("Definition cannot have both initial value and explicit address") + location = LocationRef(type, name) - return Defn(name=name, addr=addr, location=location) + + return Defn(name=name, addr=addr, initial=initial, location=location) def constraints(self): inputs = set() diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index e018656..e15ed41 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -77,6 +77,8 @@ Access a defined memory location. | } = 00c0a0008c09c0ad09c060 +Memory location with explicit address. + | byte screen @ 1024 | | routine main @@ -87,6 +89,18 @@ Access a defined memory location. | } = 00c0a9648d000460 +Memory location with initial value. + + | byte lives : 3 + | + | routine main + | inputs lives + | trashes a, z, n + | { + | ld a, lives + | } + = 00c0ad04c06003 + Some instructions. | byte foo diff --git a/tests/SixtyPical Execution.md b/tests/SixtyPical Execution.md index 1b526d0..041271c 100644 --- a/tests/SixtyPical Execution.md +++ b/tests/SixtyPical Execution.md @@ -45,6 +45,22 @@ Program accesses a memory location. = y: 0 = z: 0 +Program accesses a memory location with initial value. + + | byte lives : 3 + | + | routine main { + | ld a, lives + | } + = a: 3 + = c: 0 + = lives: 3 + = n: 0 + = v: 0 + = x: 0 + = y: 0 + = z: 0 + Add honours carry. | routine main { diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md index 4c3eb47..9912335 100644 --- a/tests/SixtyPical Syntax.md +++ b/tests/SixtyPical Syntax.md @@ -123,7 +123,7 @@ Repeat with not | } = ok -Extern memory locations. +Explicit memory address. | byte screen @ 1024 | @@ -135,7 +135,7 @@ Extern memory locations. Initialized memory locations. - | byte lives = 3 + | byte lives : 3 | | routine main { | ld a, lives @@ -143,6 +143,16 @@ Initialized memory locations. | } = ok +Cannot have both initial value and explicit address. + + | byte screen : 3 @ 1024 + | + | routine main { + | ld a, lives + | st a, lives + | } + ? SyntaxError + Can't access an undeclared memory location. | routine main {