diff --git a/codeCore/src/prog8/code/target/NormalMemSizer.kt b/codeCore/src/prog8/code/target/NormalMemSizer.kt index d8ebf15b2..0c1cc3d91 100644 --- a/codeCore/src/prog8/code/target/NormalMemSizer.kt +++ b/codeCore/src/prog8/code/target/NormalMemSizer.kt @@ -32,7 +32,7 @@ internal class NormalMemSizer(val floatsize: Int, val pointerSize: Int = 2): IMe dt.isLong -> 4 * (numElements ?: 1) dt.isWord -> 2 * (numElements ?: 1) dt.isPointer -> pointerSize * (numElements ?: 1) - dt.isStructInstance -> dt.subType!!.memsize(this) + dt.isStructInstance -> dt.subType?.memsize(this) ?: 0 dt.isUndefined -> throw IllegalArgumentException("undefined has no memory size") else -> throw IllegalArgumentException("invalid dt $dt") } diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index a94dedebe..966d02b28 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -498,17 +498,17 @@ extsub $ff41 = GRAPH_put_next_char(ubyte character @A) clobbers(A,X,Y) ; al ; framebuffer extsub $fef6 = FB_init() clobbers(A,X,Y) extsub $fef9 = FB_get_info() clobbers(X,Y) -> byte @A, uword @R0, uword @R1 ; width=r0, height=r1 -extsub $fefc = FB_set_palette(uword pointer @R0, ubyte index @A, ubyte colorcount @X) clobbers(A,X,Y) ; note: palette array must be @nosplit +extsub $fefc = FB_set_palette(uword ptr @R0, ubyte index @A, ubyte colorcount @X) clobbers(A,X,Y) ; note: palette array must be @nosplit extsub $feff = FB_cursor_position(uword x @R0, uword y @R1) clobbers(A,X,Y) extsub $ff02 = FB_cursor_next_line(uword x @R0) clobbers(A,X,Y) extsub $ff05 = FB_get_pixel() clobbers(X,Y) -> ubyte @A -extsub $ff08 = FB_get_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y) +extsub $ff08 = FB_get_pixels(uword ptr @R0, uword count @R1) clobbers(A,X,Y) extsub $ff0b = FB_set_pixel(ubyte color @A) clobbers(A,X,Y) -extsub $ff0e = FB_set_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y) +extsub $ff0e = FB_set_pixels(uword ptr @R0, uword count @R1) clobbers(A,X,Y) extsub $ff11 = FB_set_8_pixels(ubyte pattern @A, ubyte color @X) clobbers(A,X,Y) extsub $ff14 = FB_set_8_pixels_opaque(ubyte pattern @R0, ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y) extsub $ff17 = FB_fill_pixels(uword count @R0, uword pstep @R1, ubyte color @A) clobbers(A,X,Y) -extsub $ff1a = FB_filter_pixels(uword pointer @ R0, uword count @R1) clobbers(A,X,Y) +extsub $ff1a = FB_filter_pixels(uword ptr @ R0, uword count @R1) clobbers(A,X,Y) extsub $ff1d = FB_move_pixels(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword count @R4) clobbers(A,X,Y) ; misc @@ -526,7 +526,7 @@ extsub $feed = memory_decompress(uword input @R0, uword output @R1) clobbers(A, extsub $fedb = console_init(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y) extsub $fede = console_put_char(ubyte character @A, bool wrapping @Pc) clobbers(A,X,Y) extsub $fee1 = console_get_char() clobbers(X,Y) -> ubyte @A -extsub $fed8 = console_put_image(uword pointer @R0, uword width @R1, uword height @R2) clobbers(A,X,Y) +extsub $fed8 = console_put_image(uword ptr @R0, uword width @R1, uword height @R2) clobbers(A,X,Y) extsub $fed5 = console_set_paging_message(uword msgptr @R0) clobbers(A,X,Y) extsub $fecf = entropy_get() -> ubyte @A, ubyte @X, ubyte @Y ;; extsub $fea8 = extapi16(ubyte callnumber @A) clobbers (A,X,Y) ; not useful yet because is for 65816 cpu diff --git a/compiler/src/prog8/compiler/BuiltinFunctions.kt b/compiler/src/prog8/compiler/BuiltinFunctions.kt index a239e6cb8..4a3a508b3 100644 --- a/compiler/src/prog8/compiler/BuiltinFunctions.kt +++ b/compiler/src/prog8/compiler/BuiltinFunctions.kt @@ -169,6 +169,7 @@ private fun builtinSizeof(args: List, position: Position, program: P "long" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.LONG), position) "float" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.FLOAT), position) "bool" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.BOOL), position) + "pointer" -> return NumericLiteral.optimalInteger(program.target.memorySize(BaseDataType.POINTER), position) } } diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 44201cb04..51c3a3ae7 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -415,7 +415,7 @@ fun parseMainModule(filepath: Path, val program = Program(filepath.nameWithoutExtension, bf, compTarget) bf.program = program - val importer = ModuleImporter(program, compTarget.name, errors, sourceDirs, libraryDirs, cwd, quiet, traceImports) + val importer = ModuleImporter(program, compTarget, errors, sourceDirs, libraryDirs, cwd, quiet, traceImports) val importedModuleResult = importer.importMainModule(filepath) importedModuleResult.onErr { throw it } errors.report() diff --git a/compiler/src/prog8/compiler/ModuleImporter.kt b/compiler/src/prog8/compiler/ModuleImporter.kt index 1774ef8d8..b2a565fd1 100644 --- a/compiler/src/prog8/compiler/ModuleImporter.kt +++ b/compiler/src/prog8/compiler/ModuleImporter.kt @@ -6,6 +6,7 @@ import prog8.ast.Program import prog8.ast.SyntaxError import prog8.ast.statements.Directive import prog8.ast.statements.DirectiveArg +import prog8.code.core.ICompilationTarget import prog8.code.core.IErrorReporter import prog8.code.core.Position import prog8.code.sanitize @@ -20,7 +21,7 @@ import kotlin.io.path.exists class ModuleImporter(private val program: Program, - private val compilationTargetName: String, + private val compTarget: ICompilationTarget, val errors: IErrorReporter, sourceDirs: List, libraryDirs: List, @@ -63,7 +64,7 @@ class ModuleImporter(private val program: Program, private fun printCompileInfo(programPath: Path) { if(!quiet) { println("Compiling program ${cwd.toAbsolutePath().relativize(programPath)}") - println("Compiler target: $compilationTargetName") + println("Compiler target: ${compTarget.name}") } } @@ -75,7 +76,7 @@ class ModuleImporter(private val program: Program, } private fun importModule(src: SourceCode) : Module { - val moduleAst = Prog8Parser.parseModule(src) + val moduleAst = Prog8Parser.parseModule(src, compTarget) // Check if module already loaded (e.g., via symlink from different name) val existing = program.modules.firstOrNull { it.name == moduleAst.name } @@ -122,7 +123,7 @@ class ModuleImporter(private val program: Program, // try internal library if(importedModule == null) { - val moduleResourceSrc = getModuleFromResource("$moduleName.p8", compilationTargetName, importingModule?.name ?: "~implicit~") + val moduleResourceSrc = getModuleFromResource("$moduleName.p8", compTarget.name, importingModule?.name ?: "~implicit~") moduleResourceSrc.onOk { importedModule = importModule(it) } diff --git a/compiler/test/TestModuleImporter.kt b/compiler/test/TestModuleImporter.kt index 73b37c5be..57574b2a6 100644 --- a/compiler/test/TestModuleImporter.kt +++ b/compiler/test/TestModuleImporter.kt @@ -30,7 +30,7 @@ class TestModuleImporter: FunSpec({ } fun makeImporter(errors: IErrorReporter? = null, searchIn: Iterable) = - ModuleImporter(program, "blah", errors ?: ErrorReporterForTests(false), searchIn.toList(), emptyList(), Path(".").absolute(), false) + ModuleImporter(program, VMTarget(), errors ?: ErrorReporterForTests(false), searchIn.toList(), emptyList(), Path(".").absolute(), false) fun makeImporter(errors: IErrorReporter?, vararg searchIn: String): ModuleImporter { return makeImporter(errors, searchIn.asList()) diff --git a/compiler/test/TestPointers.kt b/compiler/test/TestPointers.kt index 03001e6ca..c44a27268 100644 --- a/compiler/test/TestPointers.kt +++ b/compiler/test/TestPointers.kt @@ -2847,4 +2847,53 @@ main { val result2 = compileText(Qemu68kTarget(), false, src, outputDir) result2 shouldNotBe null } + + test("bare pointer type keyword is converted to uword or long") { + val src = """ + %zeropage basicsafe + main { + sub start() { + pointer @shared ptrvar = 42 + ubyte @shared s1 = sizeof(ptrvar) + ubyte @shared s2 = sizeof(pointer) + } + }""" + // On VMTarget (6502-like, POINTER_MEM_SIZE=2): pointer -> uword, sizeof = 2 + val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = false)!! + val stmts = result.compilerAst.entrypoint.statements + + val ptrDecl = stmts.filterIsInstance().find { it.name == "ptrvar" }!! + ptrDecl.datatype.shouldBe(DataType.UWORD) + + val s1Assign = stmts.filterIsInstance().find { + val iref = it.target.toExpression() as? IdentifierReference + iref?.nameInSource?.last() == "s1" + }!! + (s1Assign.value as NumericLiteral).number shouldBe 2.0 + + val s2Assign = stmts.filterIsInstance().find { + val iref = it.target.toExpression() as? IdentifierReference + iref?.nameInSource?.last() == "s2" + }!! + (s2Assign.value as NumericLiteral).number shouldBe 2.0 + + // On m68k (POINTER_MEM_SIZE=4): pointer -> long, sizeof = 4 + val result68k = compileText(Qemu68kTarget(), false, src, outputDir, writeAssembly = false)!! + val stmts68k = result68k.compilerAst.entrypoint.statements + + val ptrDecl68k = stmts68k.filterIsInstance().find { it.name == "ptrvar" }!! + ptrDecl68k.datatype.shouldBe(DataType.LONG) + + val s1Assign68k = stmts68k.filterIsInstance().find { + val iref = it.target.toExpression() as? IdentifierReference + iref?.nameInSource?.last() == "s1" + }!! + (s1Assign68k.value as NumericLiteral).number shouldBe 4.0 + + val s2Assign68k = stmts68k.filterIsInstance().find { + val iref = it.target.toExpression() as? IdentifierReference + iref?.nameInSource?.last() == "s2" + }!! + (s2Assign68k.value as NumericLiteral).number shouldBe 4.0 + } }) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt b/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt index ca17991ed..4988c91ea 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2KotlinVisitor.kt @@ -19,7 +19,7 @@ import kotlin.io.path.Path import kotlin.io.path.isRegularFile -class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor(), Prog8ANTLRVisitor { +class Antlr2KotlinVisitor(val source: SourceCode, private val target: ICompilationTarget? = null): AbstractParseTreeVisitor(), Prog8ANTLRVisitor { // Cached resolved filename - computed once per visitor since it never changes during a single parse private var cachedFileName: String? = null @@ -46,8 +46,12 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor 2u) BaseDataType.LONG else BaseDataType.UWORD + return DataType.forDt(replacement) + } return DataType.forDt(base) + } val pointer = pointerDatatypeFor(dtctx.pointertype()) if(pointer!=null) return pointer diff --git a/compilerAst/src/prog8/parser/Prog8Parser.kt b/compilerAst/src/prog8/parser/Prog8Parser.kt index 4a1eff10f..a84c258a2 100644 --- a/compilerAst/src/prog8/parser/Prog8Parser.kt +++ b/compilerAst/src/prog8/parser/Prog8Parser.kt @@ -4,6 +4,7 @@ import org.antlr.v4.runtime.* import org.antlr.v4.runtime.atn.PredictionMode import prog8.ast.Module import prog8.ast.antlr.Antlr2KotlinVisitor +import prog8.code.core.ICompilationTarget import prog8.code.core.Position import prog8.code.source.SourceCode @@ -16,6 +17,48 @@ class MultipleParseErrors(val errors: List) : Exception( object Prog8Parser { + fun parseModule(src: SourceCode, target: ICompilationTarget): Module { + val lexer = Prog8ANTLRLexer(CharStreams.fromString(src.text, src.origin)) + lexer.removeErrorListeners() + val tokens = CommonTokenStream(lexer) + + // Fast path: try SLL prediction mode first (faster on correct input) + val sllErrorListener = CollectingErrorListener(src) + lexer.addErrorListener(sllErrorListener) + val parser = Prog8ANTLRParser(tokens) + parser.interpreter.predictionMode = PredictionMode.SLL + parser.errorHandler = DefaultErrorStrategy() + parser.removeErrorListeners() + parser.addErrorListener(sllErrorListener) + + val parseTree = parser.module() + + if(!sllErrorListener.hasErrors()) { + // SLL succeeded cleanly — use this tree + val visitor = Antlr2KotlinVisitor(src, target) + val visitorResult = visitor.visit(parseTree) + return visitorResult as Module + } + + // SLL found errors — fall back to LL for full context parsing + val llErrorListener = CollectingErrorListener(src) + lexer.reset() + parser.reset() + parser.interpreter.predictionMode = PredictionMode.LL + parser.removeErrorListeners() + parser.addErrorListener(llErrorListener) + + val llParseTree = parser.module() + + if(llErrorListener.hasErrors()) { + throw MultipleParseErrors(llErrorListener.getErrors()) + } + + val visitor = Antlr2KotlinVisitor(src, target) + val visitorResult = visitor.visit(llParseTree) + return visitorResult as Module + } + fun parseModule(src: SourceCode): Module { val lexer = Prog8ANTLRLexer(CharStreams.fromString(src.text, src.origin)) lexer.removeErrorListeners() diff --git a/docs/source/_static/symboldumps/skeletons-c128.txt b/docs/source/_static/symboldumps/skeletons-c128.txt index e377fb302..83438fe2b 100644 --- a/docs/source/_static/symboldumps/skeletons-c128.txt +++ b/docs/source/_static/symboldumps/skeletons-c128.txt @@ -1,6 +1,6 @@ Prog8 compiler v12.3-SNAPSHOT by Irmen de Jong (irmen@razorvine.net) -Prerelease version from git commit cb240f6a in branch new-codegens +Prerelease version from git commit e9ff2de4 in branch new-codegens This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-c128.p8 @@ -16,7 +16,7 @@ callfar2 (ubyte bank, uword address, ubyte argA, ubyte argX, ubyte argY, bool a clamp (byte value, byte minimum, byte maximum) -> undefined cmp (ubyte|byte|uword|word|long value1, ubyte|byte|uword|word|long|float value2) divmod (ubyte|uword dividend, ubyte|uword divisor) -> undefined, undefined -len (str|array|array_splitw values) -> uword +len (str|array|array_splitw|array_pointer values) -> uword lmh (long value) -> ubyte, ubyte, ubyte lsb (uword|word|long value) -> ubyte lsw (uword|word|long value) -> uword @@ -29,18 +29,18 @@ mkword (ubyte msb, ubyte lsb) -> uword msb (uword|word|long value) -> ubyte msw (uword|word|long value) -> uword offsetof (ubyte field) -> ubyte -peek (uword address) -> ubyte -peekbool (uword address) -> bool -peekf (uword address) -> float -peekl (uword address) -> long -peekw (uword address) -> uword -poke (uword address, ubyte|byte value) -pokebool (uword address, bool value) -pokebowl (uword address, bool value) -pokef (uword address, float value) -pokel (uword address, long value) +peek (uword|long address) -> ubyte +peekbool (uword|long address) -> bool +peekf (uword|long address) -> float +peekl (uword|long address) -> long +peekw (uword|long address) -> uword +poke (uword|long address, ubyte|byte value) +pokebool (uword|long address, bool value) +pokebowl (uword|long address, bool value) +pokef (uword|long address, float value) +pokel (uword|long address, long value) pokemon (uword address, ubyte value) -> ubyte -pokew (uword address, uword|word value) +pokew (uword|long address, uword|word value) pop () -> ubyte popf () -> float popl () -> long @@ -202,8 +202,8 @@ coroutines { const ubyte MAX_TASKS ubyte active_task uword supervisor - uword[] tasklist - uword[] userdatas + @nosplit uword[] tasklist + @nosplit uword[] userdatas add (uword taskaddress, uword userdata) -> ubyte current () -> ubyte kill (ubyte taskid) @@ -218,7 +218,7 @@ LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - uword[] logo_lines + @nosplit uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } diff --git a/docs/source/_static/symboldumps/skeletons-c64.txt b/docs/source/_static/symboldumps/skeletons-c64.txt index f8edca1fa..3f827d0c9 100644 --- a/docs/source/_static/symboldumps/skeletons-c64.txt +++ b/docs/source/_static/symboldumps/skeletons-c64.txt @@ -1,6 +1,6 @@ Prog8 compiler v12.3-SNAPSHOT by Irmen de Jong (irmen@razorvine.net) -Prerelease version from git commit cb240f6a in branch new-codegens +Prerelease version from git commit e9ff2de4 in branch new-codegens This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-c64.p8 @@ -16,7 +16,7 @@ callfar2 (ubyte bank, uword address, ubyte argA, ubyte argX, ubyte argY, bool a clamp (byte value, byte minimum, byte maximum) -> undefined cmp (ubyte|byte|uword|word|long value1, ubyte|byte|uword|word|long|float value2) divmod (ubyte|uword dividend, ubyte|uword divisor) -> undefined, undefined -len (str|array|array_splitw values) -> uword +len (str|array|array_splitw|array_pointer values) -> uword lmh (long value) -> ubyte, ubyte, ubyte lsb (uword|word|long value) -> ubyte lsw (uword|word|long value) -> uword @@ -29,18 +29,18 @@ mkword (ubyte msb, ubyte lsb) -> uword msb (uword|word|long value) -> ubyte msw (uword|word|long value) -> uword offsetof (ubyte field) -> ubyte -peek (uword address) -> ubyte -peekbool (uword address) -> bool -peekf (uword address) -> float -peekl (uword address) -> long -peekw (uword address) -> uword -poke (uword address, ubyte|byte value) -pokebool (uword address, bool value) -pokebowl (uword address, bool value) -pokef (uword address, float value) -pokel (uword address, long value) +peek (uword|long address) -> ubyte +peekbool (uword|long address) -> bool +peekf (uword|long address) -> float +peekl (uword|long address) -> long +peekw (uword|long address) -> uword +poke (uword|long address, ubyte|byte value) +pokebool (uword|long address, bool value) +pokebowl (uword|long address, bool value) +pokef (uword|long address, float value) +pokel (uword|long address, long value) pokemon (uword address, ubyte value) -> ubyte -pokew (uword address, uword|word value) +pokew (uword|long address, uword|word value) pop () -> ubyte popf () -> float popl () -> long @@ -202,8 +202,8 @@ coroutines { const ubyte MAX_TASKS ubyte active_task uword supervisor - uword[] tasklist - uword[] userdatas + @nosplit uword[] tasklist + @nosplit uword[] userdatas add (uword taskaddress, uword userdata) -> ubyte current () -> ubyte kill (ubyte taskid) @@ -218,7 +218,7 @@ LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - uword[] logo_lines + @nosplit uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } diff --git a/docs/source/_static/symboldumps/skeletons-cx16.txt b/docs/source/_static/symboldumps/skeletons-cx16.txt index 9803e90cb..4eb6a6d8a 100644 --- a/docs/source/_static/symboldumps/skeletons-cx16.txt +++ b/docs/source/_static/symboldumps/skeletons-cx16.txt @@ -1,6 +1,6 @@ Prog8 compiler v12.3-SNAPSHOT by Irmen de Jong (irmen@razorvine.net) -Prerelease version from git commit cb240f6a in branch new-codegens +Prerelease version from git commit e9ff2de4 in branch new-codegens This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-cx16.p8 @@ -16,7 +16,7 @@ callfar2 (ubyte bank, uword address, ubyte argA, ubyte argX, ubyte argY, bool a clamp (byte value, byte minimum, byte maximum) -> undefined cmp (ubyte|byte|uword|word|long value1, ubyte|byte|uword|word|long|float value2) divmod (ubyte|uword dividend, ubyte|uword divisor) -> undefined, undefined -len (str|array|array_splitw values) -> uword +len (str|array|array_splitw|array_pointer values) -> uword lmh (long value) -> ubyte, ubyte, ubyte lsb (uword|word|long value) -> ubyte lsw (uword|word|long value) -> uword @@ -29,18 +29,18 @@ mkword (ubyte msb, ubyte lsb) -> uword msb (uword|word|long value) -> ubyte msw (uword|word|long value) -> uword offsetof (ubyte field) -> ubyte -peek (uword address) -> ubyte -peekbool (uword address) -> bool -peekf (uword address) -> float -peekl (uword address) -> long -peekw (uword address) -> uword -poke (uword address, ubyte|byte value) -pokebool (uword address, bool value) -pokebowl (uword address, bool value) -pokef (uword address, float value) -pokel (uword address, long value) +peek (uword|long address) -> ubyte +peekbool (uword|long address) -> bool +peekf (uword|long address) -> float +peekl (uword|long address) -> long +peekw (uword|long address) -> uword +poke (uword|long address, ubyte|byte value) +pokebool (uword|long address, bool value) +pokebowl (uword|long address, bool value) +pokef (uword|long address, float value) +pokel (uword|long address, long value) pokemon (uword address, ubyte value) -> ubyte -pokew (uword address, uword|word value) +pokew (uword|long address, uword|word value) pop () -> ubyte popf () -> float popl () -> long @@ -73,7 +73,7 @@ adpcm { uword @requirezp pstep uword @requirezp pstep_2 byte[] t_index - uword[] t_step + @nosplit uword[] t_step decode_block_mono (uword nibblesptr) decode_block_stereo (uword nibblesptr) decode_nibble (ubyte nibble) @@ -261,8 +261,8 @@ coroutines { const ubyte MAX_TASKS ubyte active_task uword supervisor - uword[] tasklist - uword[] userdatas + @nosplit uword[] tasklist + @nosplit uword[] userdatas add (uword taskaddress, uword userdata) -> ubyte current () -> ubyte kill (ubyte taskid) @@ -277,7 +277,7 @@ LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - uword[] logo_lines + @nosplit uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -662,7 +662,7 @@ monogfx { uword height bool lores_mode ubyte mode - uword[] @shared times40 + @nosplit uword[] @shared times40 uword width circle (uword xcenter, uword ycenter, ubyte radius, bool draw) clear_screen (bool draw) @@ -736,7 +736,7 @@ psg { ubyte[] envelope_releases ubyte[] envelope_states ubyte[] envelope_sustains - uword[] envelope_volumes + @nosplit uword[] envelope_volumes bool[] voice_enabled envelope (ubyte voice_num, ubyte maxvolume, ubyte attack, ubyte sustain, ubyte release) envelopes_irq () -> bool @@ -1321,17 +1321,17 @@ cx16 { FB_cursor_next_line (uword x @R0) clobbers (A,X,Y) = $ff02 FB_cursor_position (uword x @R0, uword y @R1) clobbers (A,X,Y) = $feff FB_fill_pixels (uword count @R0, uword pstep @R1, ubyte color @A) clobbers (A,X,Y) = $ff17 - FB_filter_pixels (uword pointer @R0, uword count @R1) clobbers (A,X,Y) = $ff1a + FB_filter_pixels (uword ptr @R0, uword count @R1) clobbers (A,X,Y) = $ff1a FB_get_info () clobbers (X,Y) -> byte @A, uword @R0, uword @R1 = $fef9 FB_get_pixel () clobbers (X,Y) -> ubyte @A = $ff05 - FB_get_pixels (uword pointer @R0, uword count @R1) clobbers (A,X,Y) = $ff08 + FB_get_pixels (uword ptr @R0, uword count @R1) clobbers (A,X,Y) = $ff08 FB_init () clobbers (A,X,Y) = $fef6 FB_move_pixels (uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword count @R4) clobbers (A,X,Y) = $ff1d FB_set_8_pixels (ubyte pattern @A, ubyte color @X) clobbers (A,X,Y) = $ff11 FB_set_8_pixels_opaque (ubyte pattern @R0, ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers (A,X,Y) = $ff14 - FB_set_palette (uword pointer @R0, ubyte index @A, ubyte colorcount @X) clobbers (A,X,Y) = $fefc + FB_set_palette (uword ptr @R0, ubyte index @A, ubyte colorcount @X) clobbers (A,X,Y) = $fefc FB_set_pixel (ubyte color @A) clobbers (A,X,Y) = $ff0b - FB_set_pixels (uword pointer @R0, uword count @R1) clobbers (A,X,Y) = $ff0e + FB_set_pixels (uword ptr @R0, uword count @R1) clobbers (A,X,Y) = $ff0e GRAPH_clear () clobbers (A,X,Y) = $ff23 GRAPH_draw_image (uword x @R0, uword y @R1, uword ptr @R2, uword width @R3, uword height @R4) clobbers (A,X,Y) = $ff38 GRAPH_draw_line (uword x1 @R0, uword y1 @R1, uword x2 @R2, uword y2 @R3) clobbers (A,X,Y) = $ff2c @@ -1369,7 +1369,7 @@ cx16 { console_get_char () clobbers (X,Y) -> ubyte @A = $fee1 console_init (uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers (A,X,Y) = $fedb console_put_char (ubyte character @A, bool wrapping @Pc) clobbers (A,X,Y) = $fede - console_put_image (uword pointer @R0, uword width @R1, uword height @R2) clobbers (A,X,Y) = $fed8 + console_put_image (uword ptr @R0, uword width @R1, uword height @R2) clobbers (A,X,Y) = $fed8 console_set_paging_message (uword msgptr @R0) clobbers (A,X,Y) = $fed5 disable_irq_handlers () disable_irqs () clobbers (A) diff --git a/docs/source/_static/symboldumps/skeletons-pet32.txt b/docs/source/_static/symboldumps/skeletons-pet32.txt index 5e22a567c..dec5efb7f 100644 --- a/docs/source/_static/symboldumps/skeletons-pet32.txt +++ b/docs/source/_static/symboldumps/skeletons-pet32.txt @@ -1,6 +1,6 @@ Prog8 compiler v12.3-SNAPSHOT by Irmen de Jong (irmen@razorvine.net) -Prerelease version from git commit cb240f6a in branch new-codegens +Prerelease version from git commit e9ff2de4 in branch new-codegens This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-pet32.p8 @@ -16,7 +16,7 @@ callfar2 (ubyte bank, uword address, ubyte argA, ubyte argX, ubyte argY, bool a clamp (byte value, byte minimum, byte maximum) -> undefined cmp (ubyte|byte|uword|word|long value1, ubyte|byte|uword|word|long|float value2) divmod (ubyte|uword dividend, ubyte|uword divisor) -> undefined, undefined -len (str|array|array_splitw values) -> uword +len (str|array|array_splitw|array_pointer values) -> uword lmh (long value) -> ubyte, ubyte, ubyte lsb (uword|word|long value) -> ubyte lsw (uword|word|long value) -> uword @@ -29,18 +29,18 @@ mkword (ubyte msb, ubyte lsb) -> uword msb (uword|word|long value) -> ubyte msw (uword|word|long value) -> uword offsetof (ubyte field) -> ubyte -peek (uword address) -> ubyte -peekbool (uword address) -> bool -peekf (uword address) -> float -peekl (uword address) -> long -peekw (uword address) -> uword -poke (uword address, ubyte|byte value) -pokebool (uword address, bool value) -pokebowl (uword address, bool value) -pokef (uword address, float value) -pokel (uword address, long value) +peek (uword|long address) -> ubyte +peekbool (uword|long address) -> bool +peekf (uword|long address) -> float +peekl (uword|long address) -> long +peekw (uword|long address) -> uword +poke (uword|long address, ubyte|byte value) +pokebool (uword|long address, bool value) +pokebowl (uword|long address, bool value) +pokef (uword|long address, float value) +pokel (uword|long address, long value) pokemon (uword address, ubyte value) -> ubyte -pokew (uword address, uword|word value) +pokew (uword|long address, uword|word value) pop () -> ubyte popf () -> float popl () -> long @@ -202,8 +202,8 @@ coroutines { const ubyte MAX_TASKS ubyte active_task uword supervisor - uword[] tasklist - uword[] userdatas + @nosplit uword[] tasklist + @nosplit uword[] userdatas add (uword taskaddress, uword userdata) -> ubyte current () -> ubyte kill (ubyte taskid) @@ -218,7 +218,7 @@ LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - uword[] logo_lines + @nosplit uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } diff --git a/docs/source/_static/symboldumps/skeletons-qemu68k.txt b/docs/source/_static/symboldumps/skeletons-qemu68k.txt index e98f3ab4d..925e76a51 100644 --- a/docs/source/_static/symboldumps/skeletons-qemu68k.txt +++ b/docs/source/_static/symboldumps/skeletons-qemu68k.txt @@ -1,6 +1,6 @@ Prog8 compiler v12.3-SNAPSHOT by Irmen de Jong (irmen@razorvine.net) -Prerelease version from git commit cb240f6a in branch new-codegens +Prerelease version from git commit e9ff2de4 in branch new-codegens This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-qemu68k.p8 @@ -16,7 +16,7 @@ callfar2 (ubyte bank, uword address, ubyte argA, ubyte argX, ubyte argY, bool a clamp (byte value, byte minimum, byte maximum) -> undefined cmp (ubyte|byte|uword|word|long value1, ubyte|byte|uword|word|long|float value2) divmod (ubyte|uword dividend, ubyte|uword divisor) -> undefined, undefined -len (str|array|array_splitw values) -> uword +len (str|array|array_splitw|array_pointer values) -> uword lmh (long value) -> ubyte, ubyte, ubyte lsb (uword|word|long value) -> ubyte lsw (uword|word|long value) -> uword @@ -29,18 +29,18 @@ mkword (ubyte msb, ubyte lsb) -> uword msb (uword|word|long value) -> ubyte msw (uword|word|long value) -> uword offsetof (ubyte field) -> ubyte -peek (uword address) -> ubyte -peekbool (uword address) -> bool -peekf (uword address) -> float -peekl (uword address) -> long -peekw (uword address) -> uword -poke (uword address, ubyte|byte value) -pokebool (uword address, bool value) -pokebowl (uword address, bool value) -pokef (uword address, float value) -pokel (uword address, long value) +peek (uword|long address) -> ubyte +peekbool (uword|long address) -> bool +peekf (uword|long address) -> float +peekl (uword|long address) -> long +peekw (uword|long address) -> uword +poke (uword|long address, ubyte|byte value) +pokebool (uword|long address, bool value) +pokebowl (uword|long address, bool value) +pokef (uword|long address, float value) +pokel (uword|long address, long value) pokemon (uword address, ubyte value) -> ubyte -pokew (uword address, uword|word value) +pokew (uword|long address, uword|word value) pop () -> ubyte popf () -> float popl () -> long @@ -176,6 +176,8 @@ floats { const float PI const float TWOPI const float π + print (float value @FP0) + tostr (float value @FP0) -> str @A0 } @@ -234,9 +236,14 @@ LIBRARY MODULE NAME: strings ---------------------------- strings { + compare (str st1 @D0, str st2 @D1) -> byte @D0 + copy (str source @D0, str target @D1) -> ubyte @D0 + hash (str string @D0) -> ubyte @D0 isdigit (ubyte char) -> bool isxdigit (ubyte char) -> bool + length (str string @D0) -> ubyte @D0 lowerchar (ubyte char) -> ubyte + ncopy (str source @D0, str target @D1, ubyte maxlength @D2) -> ubyte @D0 } @@ -244,6 +251,26 @@ LIBRARY MODULE NAME: syslib --------------------------- qemu { + const uword BI_COMMAND_LINE + const uword BI_CPUTYPE + const uword BI_FPUTYPE + const uword BI_LAST + const uword BI_MACHTYPE + const uword BI_MEMCHUNK + const uword BI_MMUTYPE + const uword BI_RAMDISK + const uword BI_RNG_SEED + const uword BI_VIRT_CTRL_BASE + const uword BI_VIRT_GF_PIC_BASE + const uword BI_VIRT_GF_RTC_BASE + const uword BI_VIRT_GF_TTY_BASE + const uword BI_VIRT_QEMU_VERSION + const uword BI_VIRT_VIRTIO_BASE + const long CPU_FEATURE_68020 + const long CPU_FEATURE_68030 + const long CPU_FEATURE_68040 + const long CPU_FEATURE_68060 + const long CPU_FEATURE_COLDFIRE const ubyte CTRL_CMD_HALT const ubyte CTRL_CMD_NOOP const ubyte CTRL_CMD_PANIC @@ -253,6 +280,20 @@ qemu { const long GF_PIC_BASE const long GF_RTC_BASE const long GF_TTY_BASE + const long MACH_AMIGA + const long MACH_APOLLO + const long MACH_ATARI + const long MACH_BVME6000 + const long MACH_HP300 + const long MACH_M5441x + const long MACH_M54xx + const long MACH_MAC + const long MACH_MVME147 + const long MACH_MVME16x + const long MACH_Q40 + const long MACH_SUN3 + const long MACH_SUN3x + const long MACH_VIRT const ubyte PIC_REG_DISABLE const ubyte PIC_REG_ENABLE const ubyte PIC_REG_IRQ_DISABLE_ALL @@ -279,6 +320,14 @@ qemu { const long TTY_VERSION const long VIRTIO_BASE const long VIRT_CTRL_BASE + bootinfo_dump () + bootinfo_next (long ptr) -> long + bootinfo_ptr () -> long + chrin () -> ubyte @D0 + chrout (ubyte char @D0) + input_data (long buffer @A0, uword maxlen @D1) -> uword @D0 + keypressed () -> bool @Pz + puts (str msg @A0) } sys { @@ -305,11 +354,13 @@ sys { clear_irqd () die (ubyte code, str message) exit (ubyte returnvalue) - memcopy (^^ubyte source, ^^ubyte tgt, uword count) - memset (^^ubyte mem, uword numbytes, ubyte value) + memclear (long mem @D0, uword numbytes @D1) + memcopy (long source @D0, long tgt @D1, uword count @D2) + memset (long mem @D0, uword numbytes @D1, ubyte value @D2) + memsetw (long mem @D0, uword numwords @D1, uword value @D2) poweroff_system () - progend () -> long @D0 - progstart () -> long + progend () -> long @A0 + progstart () -> long @A0 reset_system () set_carry () set_irqd () @@ -321,17 +372,23 @@ LIBRARY MODULE NAME: textio --------------------------- txt { - chrout (ubyte char) + bell () + chrin alias for: qemu.chrin + chrout (ubyte char @D0) clear_screen () cls () + color (ubyte txtcol) + column (ubyte col) home () + input_chars (str buffer) -> ubyte iso () - iso_off () + keypressed alias for: qemu.keypressed lowercase () nl () - print (str text) + print (str text @A0) print_b (byte value) print_bool (bool value) + print_f alias for: floats.print print_l (long value) print_ub (ubyte value) print_ub0 (ubyte value) @@ -346,7 +403,6 @@ txt { rvs_off () rvs_on () spc () - uppercase () } diff --git a/docs/source/_static/symboldumps/skeletons-virtual.txt b/docs/source/_static/symboldumps/skeletons-virtual.txt index 2e7854d3d..5815bdba8 100644 --- a/docs/source/_static/symboldumps/skeletons-virtual.txt +++ b/docs/source/_static/symboldumps/skeletons-virtual.txt @@ -1,6 +1,6 @@ Prog8 compiler v12.3-SNAPSHOT by Irmen de Jong (irmen@razorvine.net) -Prerelease version from git commit cb240f6a in branch new-codegens +Prerelease version from git commit e9ff2de4 in branch new-codegens This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-virtual.p8 @@ -16,7 +16,7 @@ callfar2 (ubyte bank, uword address, ubyte argA, ubyte argX, ubyte argY, bool a clamp (byte value, byte minimum, byte maximum) -> undefined cmp (ubyte|byte|uword|word|long value1, ubyte|byte|uword|word|long|float value2) divmod (ubyte|uword dividend, ubyte|uword divisor) -> undefined, undefined -len (str|array|array_splitw values) -> uword +len (str|array|array_splitw|array_pointer values) -> uword lmh (long value) -> ubyte, ubyte, ubyte lsb (uword|word|long value) -> ubyte lsw (uword|word|long value) -> uword @@ -29,18 +29,18 @@ mkword (ubyte msb, ubyte lsb) -> uword msb (uword|word|long value) -> ubyte msw (uword|word|long value) -> uword offsetof (ubyte field) -> ubyte -peek (uword address) -> ubyte -peekbool (uword address) -> bool -peekf (uword address) -> float -peekl (uword address) -> long -peekw (uword address) -> uword -poke (uword address, ubyte|byte value) -pokebool (uword address, bool value) -pokebowl (uword address, bool value) -pokef (uword address, float value) -pokel (uword address, long value) +peek (uword|long address) -> ubyte +peekbool (uword|long address) -> bool +peekf (uword|long address) -> float +peekl (uword|long address) -> long +peekw (uword|long address) -> uword +poke (uword|long address, ubyte|byte value) +pokebool (uword|long address, bool value) +pokebowl (uword|long address, bool value) +pokef (uword|long address, float value) +pokel (uword|long address, long value) pokemon (uword address, ubyte value) -> ubyte -pokew (uword address, uword|word value) +pokew (uword|long address, uword|word value) pop () -> ubyte popf () -> float popl () -> long @@ -171,7 +171,7 @@ LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - uword[] logo_lines + @nosplit uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } diff --git a/docs/source/conf.py b/docs/source/conf.py index 54cc0eb0d..acda705f3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -18,7 +18,14 @@ # -- Project information ----------------------------------------------------- +import os import subprocess +import sys + +# -- Path setup -------------------------------------------------------------- + +# Add the docs source directory to sys.path so custom modules like prog8_lexer can be imported +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) project = "Prog8" copyright = "Irmen de Jong" @@ -70,6 +77,10 @@ else: def setup(app): # add custom css app.add_css_file("css/customize.css") + # register custom Prog8 Pygments lexer + from prog8_lexer import Prog8Lexer + from sphinx.highlighting import lexers + lexers["prog8"] = Prog8Lexer() # -- General configuration --------------------------------------------------- diff --git a/docs/source/prog8_lexer.py b/docs/source/prog8_lexer.py new file mode 100644 index 000000000..313100703 --- /dev/null +++ b/docs/source/prog8_lexer.py @@ -0,0 +1,63 @@ +from pygments.lexer import RegexLexer, include +from pygments.token import * + + +class Prog8Lexer(RegexLexer): + name = "Prog8" + aliases = ["prog8"] + filenames = ["*.p8"] + + tokens = { + "root": [ + (r";.*$", Comment.Single), + (r"/\*", Comment.Multiline, "blockcomment"), + (r'"', String, "string"), + ("'", String, "char"), + (r"\d+\.\d+(?:[eE][+-]?\d+)?", Number.Float), + (r"\d+", Number.Integer), + (r"\$[0-9a-fA-F_]+", Number.Hex), + (r"%[01_]+", Number.Bin), + (r"\btrue\b|\bfalse\b", Keyword.Constant), + (r"\b(?:if|else|then|when)\b", Keyword), + (r"\b(?:if_cs|if_cc|if_vs|if_vc|if_eq|if_z|if_ne|if_nz|if_pl|if_pos|if_mi|if_neg)\b", Keyword), + (r"\b(?:for|while|do|until|repeat|unroll|in|to|downto|step)\b", Keyword), + (r"\b(?:break|continue|goto|return|defer|swap)\b", Keyword), + (r"\b(?:sub|asmsub|extsub|inline|private|clobbers)\b", Keyword.Declaration), + (r"\b(?:const|enum|struct|alias|memory)\b", Keyword.Declaration), + (r"\b(?:ubyte|byte|uword|word|long|float|str|bool|pointer)\b", Keyword.Type), + (r"\bvoid\b", Keyword.Type), + (r"\b(?:and|or|xor|not|as)\b", Operator.Word), + (r"%\w+", Name.Decorator), + (r"@\w+", Name.Decorator), + (r"\^\^", Keyword.Type), + (r"\+\+|--", Operator), + (r"(?:<<=|>>=)", Operator), + (r"<<|>>", Operator), + (r"&&|\|\|", Operator), + (r"[-+*/%&|^~<>!]=?", Operator), + (r"[{}()\[\]]", Punctuation), + (r":", Punctuation), + (r",", Punctuation), + (r"\.", Punctuation), + (r"\s+", Text), + (r"[a-zA-Z_][a-zA-Z0-9_]*", Name), + ], + "string": [ + (r'\\[\\"\'nrtxXuU0]', String.Escape), + (r'"', String, "#pop"), + (r"[^\\\"]+", String), + (r"\\", String), + ], + "char": [ + (r"\\(?:[\\\"'nrtxXuU0])", String.Escape), + (r"'", String, "#pop"), + (r"[^\\']+", String), + (r"\\", String), + ], + "blockcomment": [ + (r"[^*/]+", Comment.Multiline), + (r"/\*", Comment.Multiline, "#push"), + (r"\*/", Comment.Multiline, "#pop"), + (r"[*/]", Comment.Multiline), + ], + } diff --git a/docs/source/structpointers.rst b/docs/source/structpointers.rst index fe18430ec..f1807611e 100644 --- a/docs/source/structpointers.rst +++ b/docs/source/structpointers.rst @@ -39,9 +39,9 @@ Structs and Pointers thenode.field = 9999 -Legacy untyped pointers (uword) -------------------------------- -.. index:: single: Pointers; legacy untyped +Untyped pointers and the ``pointer`` type +----------------------------------------- +.. index:: single: Pointers; untyped Prior to version 12 of the language, the only pointer type available was a plain ``uword`` value (the memory address) which could be used as a pointer to an ``ubyte`` (the byte value at that memory address). @@ -54,13 +54,22 @@ explicitly for what it actually pointed to, if that wasn't a simple byte. Some implicit conversions were allowed too (such as putting ``str`` as the type of a subroutine parameter, which would be changed to ``uword`` by the compiler). -Since Prog8 version 12 there now are *typed pointers* that better express the intent and tell the compiler how to use the pointer; -these are explained below. +Since version 12.6 there now is a dedicated ``pointer`` type keyword that serves as an untyped address +and automatically takes the size of memory addresses on the target system. +On 6502-based systems (C64, CX16, C128, PET32) it is 2 bytes (equivalent to ``uword``). +On the m68k target (qemu68k) it is 4 bytes (equivalent to ``long``). +This is useful when writing code that is compiled for different targets, +because you don't need to manually switch between ``uword`` and ``long`` via conditional compilation:: -*For backward compatibility reasons, this untyped uword pointer still exists in the language.* -You can assign any other pointer type to an untyped pointer variable (uword) without the need for an explicit cast. -You can assign an untyped pointer (uword) to a typed pointer variable without the need for an explicit cast. + pointer ptr = $a000 + ; same program works on both 6502 and m68k targets + ; ptr is 2 bytes on C64, CX16, etc. + ; ptr is 4 bytes on qemu68k +You can assign any other pointer type to an untyped pointer variable (``uword``, ``long``` or ``pointer``) without the need for an explicit cast. +You can assign an untyped pointer to a typed pointer variable without the need for an explicit cast. +Prog8 *typed pointers* better express the intent and better tell the compiler how to use the pointer. +These are preferred to be used in new code, and are explained below. Typed pointer to simple datatype diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 802bcfb06..f24f4d8f3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,7 +2,6 @@ TODO ==== - need a bunch of type casting/conversion checks that test the handling of the 4-byte/long pointer datatype on the qemu68k target. -- need a 'pointer' type that is an alias for long on m68k and uword otherwise? - some generated label names in the m68k codegen can maybe replaced by local/anonymous labels? @@ -16,6 +15,7 @@ Note: this problem does NOT affect regular data/address registers because those Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ +- use .. code-block:: prog8 in the documentation instead of 'bare' code blocks (there is a prog8 lexer now added for pygments to pick this up) - make enums strongly typed instead of just syntactic sugar for ints (see ideas/enum-strong-type.md for the plan) - add %option private_symbols to make access mode private by default; need (new) 'public' keyword to explicitly mark symbols public. - symboldump: some sort of javadocs generated from the p8 source files (instead of just the function signatures). Use markdown for formatting, not html. diff --git a/docs/source/variables.rst b/docs/source/variables.rst index e2ee62eb5..65c61e141 100644 --- a/docs/source/variables.rst +++ b/docs/source/variables.rst @@ -266,6 +266,7 @@ type identifier type storage size example var declara ``str`` string (PETSCII) varies ``str myvar = "hello."`` implicitly terminated by a 0-byte ``^^type`` typed pointer 2 bytes pointer types are explained in their own chapter :ref:`pointers` +``pointer`` untyped address 2 or 4 bytes ``pointer ptr = $a000``. See :ref:`pointers` for details. =============== ======================= ================= ========================================= Integers (bytes, words, longs) diff --git a/examples/test.p8 b/examples/test.p8 index dca9a960f..86b93909a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,198 +1,12 @@ -%import floats %import textio %zeropage basicsafe main { sub start() { - txt.print("\nHello from Prog8 in QEMU m68k!\n") -; txt.print("raw qemu bootinfo dump:\n") -; qemu.bootinfo_dump() - txt.print("\n\nparsed QEMU bootinfo:\n") - bootinfo_print() - txt.print("\nGoodbye!\n") -; str input = "?"*80 -; txt.print("Enter your name: ") -; ubyte length=txt.input_chars(input) -; txt.print("\nHello, ") -; txt.print(input) -; txt.print("!\n") -; txt.print_ub(length) -; txt.nl() + pointer @shared ptr = 777777 + txt.print_ub(sizeof(ptr)) ; expected 4 + txt.nl() + txt.print_ub(sizeof(pointer)) ; expected 4 + txt.nl() } - - sub bootinfo_print() { - long ptr = qemu.bootinfo_ptr() - repeat { - uword tag = peekw(ptr) - uword size = peekw(ptr + 2) - if tag == qemu.BI_LAST - { - txt.print(" BI_LAST\n") - break - } - uword data_count = size - 4 - long payload = ptr + 4 - - ; -- address and tag name -- - txt.print_ulhex(ptr, true) - txt.print(": ") - when tag { - qemu.BI_MACHTYPE -> txt.print("BI_MACHTYPE") - qemu.BI_CPUTYPE -> txt.print("BI_CPUTYPE") - qemu.BI_FPUTYPE -> txt.print("BI_FPUTYPE") - qemu.BI_MMUTYPE -> txt.print("BI_MMUTYPE") - qemu.BI_MEMCHUNK -> txt.print("BI_MEMCHUNK") - qemu.BI_RAMDISK -> txt.print("BI_RAMDISK") - qemu.BI_COMMAND_LINE -> txt.print("BI_COMMAND_LINE") - qemu.BI_RNG_SEED -> txt.print("BI_RNG_SEED") - qemu.BI_VIRT_QEMU_VERSION -> txt.print("BI_VIRT_QEMU_VERSION") - qemu.BI_VIRT_GF_PIC_BASE -> txt.print("BI_VIRT_GF_PIC_BASE") - qemu.BI_VIRT_GF_RTC_BASE -> txt.print("BI_VIRT_GF_RTC_BASE") - qemu.BI_VIRT_GF_TTY_BASE -> txt.print("BI_VIRT_GF_TTY_BASE") - qemu.BI_VIRT_VIRTIO_BASE -> txt.print("BI_VIRT_VIRTIO_BASE") - qemu.BI_VIRT_CTRL_BASE -> txt.print("BI_VIRT_CTRL_BASE") - else -> { - txt.print("??? (tag=") - txt.print_uwhex(tag, true) - txt.print(")") - } - } - txt.nl() - - ; -- decode payload -- - when tag { - qemu.BI_MACHTYPE -> { - long mach = peekl(payload) - txt.print(" ") - when mach { - qemu.MACH_AMIGA -> txt.print("Amiga") - qemu.MACH_ATARI -> txt.print("Atari") - qemu.MACH_MAC -> txt.print("Mac") - qemu.MACH_APOLLO -> txt.print("Apollo") - qemu.MACH_SUN3 -> txt.print("Sun3") - qemu.MACH_MVME147 -> txt.print("MVME147") - qemu.MACH_MVME16x -> txt.print("MVME16x") - qemu.MACH_BVME6000 -> txt.print("BVME6000") - qemu.MACH_HP300 -> txt.print("HP300") - qemu.MACH_Q40 -> txt.print("Q40") - qemu.MACH_SUN3x -> txt.print("Sun3x") - qemu.MACH_M54xx -> txt.print("M54xx") - qemu.MACH_M5441x -> txt.print("M5441x") - qemu.MACH_VIRT -> txt.print("VIRT") - else -> txt.print("MACH_???") - } - txt.print(" (") - txt.print_ulhex(mach, false) - txt.print(")") - } - qemu.BI_CPUTYPE -> { - long cpu = peekl(payload) - txt.print(" CPU") - if cpu==0 - txt.print("_68000") - else - { - if (cpu & qemu.CPU_FEATURE_68020) != 0 - txt.print("+68020") - if (cpu & qemu.CPU_FEATURE_68030) != 0 - txt.print("+68030") - if (cpu & qemu.CPU_FEATURE_68040) != 0 - txt.print("+68040") - if (cpu & qemu.CPU_FEATURE_68060) != 0 - txt.print("+68060") - if (cpu & qemu.CPU_FEATURE_COLDFIRE) != 0 - txt.print("+ColdFire") - } - txt.print(" (") - txt.print_ulhex(cpu, false) - txt.print(")") - } - qemu.BI_FPUTYPE, qemu.BI_MMUTYPE -> { - txt.print(" ") - txt.print_ulhex(peekl(payload), false) - } - qemu.BI_MEMCHUNK -> { - long mem_base = peekl(payload) - long mem_size = peekl(payload + 4) - txt.print(" mem at ") - txt.print_ulhex(mem_base, true) - txt.print(" - ") - txt.print_ulhex(mem_base + mem_size, true) - txt.print(" size=") - txt.print_ulhex(mem_size, true) - } - qemu.BI_RAMDISK -> { - long r_addr = peekl(payload) - long r_size = peekl(payload + 4) - txt.print(" addr=") - txt.print_ulhex(r_addr, true) - txt.print(" size=") - txt.print_ulhex(r_size, true) - } - qemu.BI_COMMAND_LINE -> { - txt.print(" \"") - uword cl_idx=0 - repeat data_count { - ubyte c = @(payload + cl_idx) - if c == 0 - break - txt.chrout(c) - cl_idx++ - } - txt.print("\"") - } - qemu.BI_RNG_SEED -> { - txt.print(" ") - txt.print_ub(data_count as ubyte) - txt.print(" bytes: ") - uword rng_idx=0 - repeat data_count { - ubyte rng_b = @(payload + rng_idx) - txt.print_ubhex(rng_b, false) - rng_idx++ - } - } - qemu.BI_VIRT_QEMU_VERSION -> { - long ver = peekl(payload) - ubyte major = (ver >> 24) as ubyte - ubyte minor = ((ver >> 16) & 255) as ubyte - txt.print(" QEMU ") - txt.print_ub(major) - txt.print(".") - txt.print_ub(minor) - txt.print(" (") - txt.print_ulhex(ver, false) - txt.print(")") - } - qemu.BI_VIRT_GF_PIC_BASE, qemu.BI_VIRT_GF_RTC_BASE, - qemu.BI_VIRT_GF_TTY_BASE, qemu.BI_VIRT_VIRTIO_BASE, - qemu.BI_VIRT_CTRL_BASE -> { - long base = peekl(payload) - long count = peekl(payload + 4) - txt.print(" base=") - txt.print_ulhex(base, true) - txt.print(" count=") - txt.print_ulhex(count, true) - } - else -> { - uword hex_idx=0 - uword hex_col=0 - repeat data_count { - if hex_col == 4 - { - txt.print(" ") - hex_col = 0 - } - ubyte hex_b = @(payload + hex_idx) - txt.print_ubhex(hex_b, false) - hex_idx++ - hex_col++ - } - } - } - txt.nl() - ptr = qemu.bootinfo_next(ptr) - } - } - } diff --git a/parser/src/main/antlr/Prog8ANTLR.g4 b/parser/src/main/antlr/Prog8ANTLR.g4 index 0d230c131..496613047 100644 --- a/parser/src/main/antlr/Prog8ANTLR.g4 +++ b/parser/src/main/antlr/Prog8ANTLR.g4 @@ -34,6 +34,7 @@ STEP: 'step'; ELSE: 'else'; THEN: 'then'; ENUM: 'enum'; +POINTERSTR: 'pointer'; UNICODEDNAME : [\p{Letter}]([\p{Letter}\p{Mark}\p{Digit}_] | '::')* ; // match unicode properties UNDERSCORENAME : '_' UNICODEDNAME ; // match unicode properties @@ -212,7 +213,7 @@ constdecl: PRIVATE? 'const' datatype? identifierlist '=' expression ; memoryvardecl: ADDRESS_OF varinitializer; -basedatatype: 'ubyte' | 'byte' | 'uword' | 'word' | 'long' | 'float' | 'str' | 'bool' ; +basedatatype: 'ubyte' | 'byte' | 'uword' | 'word' | 'long' | 'float' | 'str' | 'bool' | 'pointer' ; datatype: pointertype | basedatatype | structtype=scoped_identifier; @@ -315,7 +316,7 @@ breakstmt : 'break'; continuestmt: 'continue'; -identifier : UNICODEDNAME | UNDERSCORENAME | ON | CALL | INLINE | PRIVATE | STEP ; // due to the way antlr creates tokens, need to list the tokens here explicitly that we want to allow as identifiers too +identifier : UNICODEDNAME | UNDERSCORENAME | ON | CALL | INLINE | PRIVATE | STEP | POINTERSTR ; // due to the way antlr creates tokens, need to list the tokens here explicitly that we want to allow as identifiers too scoped_identifier : identifier ('.' identifier)* ; diff --git a/syntax-files/Jetbrains-IDEs/Prog8.xml b/syntax-files/Jetbrains-IDEs/Prog8.xml index bb7014be1..f7923e29b 100644 --- a/syntax-files/Jetbrains-IDEs/Prog8.xml +++ b/syntax-files/Jetbrains-IDEs/Prog8.xml @@ -13,11 +13,11 @@ - + - \ No newline at end of file + diff --git a/syntax-files/Kate/prog8.xml b/syntax-files/Kate/prog8.xml index 43a52d29c..1f08b2f3e 100644 --- a/syntax-files/Kate/prog8.xml +++ b/syntax-files/Kate/prog8.xml @@ -87,6 +87,7 @@ const float long + pointer str struct ubyte diff --git a/syntax-files/NotepadPlusPlus/Prog8.xml b/syntax-files/NotepadPlusPlus/Prog8.xml index 961ee65cb..9165392a0 100644 --- a/syntax-files/NotepadPlusPlus/Prog8.xml +++ b/syntax-files/NotepadPlusPlus/Prog8.xml @@ -24,7 +24,7 @@ - void const str byte ubyte bool long word uword float zp shared split nosplit requirezp nozp align64 alignpage alignword dirty struct enum + void const str byte ubyte bool long word uword float pointer zp shared split nosplit requirezp nozp align64 alignpage alignword dirty struct enum %address %asm %ir %asmbinary %asminclude %align %breakpoint %encoding %import %jmptable %memtop %launcher %option %output %zeropage %zpreserved %zpallowed inline sub asmsub extsub clobbers asm if when then else if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z for in step do while repeat unroll break continue return goto private alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lmh lsl lsr memory mkword min max msb msw offsetof peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool pop popw popl popf psg psg2 push pushw pushl pushf rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sqrt sqrtw swap diff --git a/syntax-files/NotepadPlusPlus/Prog8dark.xml b/syntax-files/NotepadPlusPlus/Prog8dark.xml index a337905db..1c42821ea 100644 --- a/syntax-files/NotepadPlusPlus/Prog8dark.xml +++ b/syntax-files/NotepadPlusPlus/Prog8dark.xml @@ -24,7 +24,7 @@ - void const str byte ubyte bool long word uword float zp shared split nosplit requirezp nozp align64 alignpage alignword dirty struct enum + void const str byte ubyte bool long word uword float pointer zp shared split nosplit requirezp nozp align64 alignpage alignword dirty struct enum %address %asm %ir %asmbinary %asminclude %align %breakpoint %encoding %import %jmptable %memtop %launcher %option %output %zeropage %zpreserved %zpallowed inline sub asmsub extsub clobbers asm if when else if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z for in step do while repeat unroll break continue return goto private alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lmh lsl lsr memory mkword min max msb msw offsetof peek peekw peekl peekf peekbool poke pokew pokel pokef pokebool pop popw popl popf psg psg2 push pushw pushl pushf rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sqrt sqrtw swap diff --git a/syntax-files/SublimeText/Prog8.sublime-syntax b/syntax-files/SublimeText/Prog8.sublime-syntax index 84cf718b2..d7208d6b3 100644 --- a/syntax-files/SublimeText/Prog8.sublime-syntax +++ b/syntax-files/SublimeText/Prog8.sublime-syntax @@ -147,9 +147,9 @@ contexts: - match: (\b\w+\.) scope: entity.name.namespace.prog8 storage: - - match: (\b(ubyte|byte|word|uword|long|float|str|bool|struct|enum)\b) + - match: (\b(ubyte|byte|word|uword|long|float|str|bool|pointer|struct|enum)\b) scope: storage.type.prog8 - - match: (\^\^(ubyte|byte|word|uword|long|float|str|bool)\b) + - match: (\^\^(ubyte|byte|word|uword|long|float|str|bool|pointer)\b) scope: storage.type.prog8 - match: (\^\^) scope: storage.modifier.prog8 diff --git a/syntax-files/Vim/prog8.vim b/syntax-files/Vim/prog8.vim index 2cc6de626..91c4af3d6 100644 --- a/syntax-files/Vim/prog8.vim +++ b/syntax-files/Vim/prog8.vim @@ -35,9 +35,9 @@ syn match prog8Directive "\(^\|\s\)%\(zpreserved\|zpallowed\|address\|encoding\| syn match prog8Directive "\(^\|\s\)%\(align\|asmbinary\|asminclude\|breakpoint\)\>" syn match prog8Directive "\(^\|\s\)%\(asm\|ir\)\>" -syn match prog8Type "\<\%(u\?byte\|u\?word\|float\|str\|bool\|long\|\^\^\)\>" +syn match prog8Type "\<\%(u\?byte\|u\?word\|float\|str\|bool\|long\|pointer\|\^\^\)\>" syn region prog8ArrayType matchgroup=prog8Type - \ start="\<\%(u\?byte\|u\?word\|float\|str\|bool\)\[" end="\]" + \ start="\<\%(u\?byte\|u\?word\|float\|str\|bool\|pointer\)\[" end="\]" \ transparent syn keyword prog8StorageClass const enum struct syn match prog8StorageClass "\(^\|\s\)\(@zp\|@bank\|@shared\|@nosplit\|@nozp\|@requirezp\|@align64\|@alignword\|@alignpage\|@dirty\)\>" diff --git a/syntax-files/nano/prog8.nanorc b/syntax-files/nano/prog8.nanorc index de95d7e68..6a7e3fd35 100644 --- a/syntax-files/nano/prog8.nanorc +++ b/syntax-files/nano/prog8.nanorc @@ -33,7 +33,7 @@ color red "\<(sub|(inline[[:space:]]+)?asmsub|extsub|else|then|void|not|and|or|x color sky "^[[:alpha:]][[:alnum:]_]*:" # Data Types -color crimson "\<(u?byte|u?word|str|bool|float|long)\>" +color crimson "\<(u?byte|u?word|str|bool|float|long|pointer)\>" # Brackets color yellow "[()]"