diff --git a/antlr/antlr.sh b/antlr/antlr.sh new file mode 100755 index 000000000..de6f9cb9b --- /dev/null +++ b/antlr/antlr.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +PROJECT=~/Projects/IL65/antlr + +export CLASSPATH=".:${PROJECT}/lib/antlr-4.7.1-complete.jar:${CLASSPATH}" +java -jar ${PROJECT}/lib/antlr-4.7.1-complete.jar $* diff --git a/antlr/examples/tinybasic.bas b/antlr/examples/tinybasic.bas new file mode 100644 index 000000000..50a16ce0f --- /dev/null +++ b/antlr/examples/tinybasic.bas @@ -0,0 +1,7 @@ +50 INPUT "GUESS A NUMBER?", G +60 C = C+1 +70 IF G=N GOTO 110 +80 IF G>N PRINT "LOWER" +90 IF G' | '=' | 'ε')?) + | ('>' ('<' | '=' | 'ε')?) + | '=' + | '+' + | '-' + ; + + +STRING + : '"' ~ ["\r\n]* '"' + ; + + +DIGIT + : '0' .. '9' + ; + + +VAR + : 'A' .. 'Z' + ; + + +CR + : [\r\n]+ + ; + + +WS + : [ \t] -> skip + ; diff --git a/antlr/grun.sh b/antlr/grun.sh new file mode 100755 index 000000000..20b9109d9 --- /dev/null +++ b/antlr/grun.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +PROJECT=~/Projects/IL65/antlr + +export CLASSPATH=".:${PROJECT}/lib/antlr-4.7.1-complete.jar:${CLASSPATH}" +java org.antlr.v4.gui.TestRig $* + diff --git a/antlr/lib/antlr-4.7.1-complete.jar b/antlr/lib/antlr-4.7.1-complete.jar new file mode 100644 index 000000000..ad02f7a46 Binary files /dev/null and b/antlr/lib/antlr-4.7.1-complete.jar differ diff --git a/antlr/lib/antlr-runtime-4.7.1.jar b/antlr/lib/antlr-runtime-4.7.1.jar new file mode 100644 index 000000000..e2e0ac72e Binary files /dev/null and b/antlr/lib/antlr-runtime-4.7.1.jar differ diff --git a/docs/source/building.rst b/docs/source/building.rst index 058734881..799f65fee 100644 --- a/docs/source/building.rst +++ b/docs/source/building.rst @@ -27,6 +27,10 @@ The compiler is invoked with the command: ``$ @todo`` +It produces an assembly source code file which in turn will (automatically) be passed to +the `64tass `_ cross assembler tool +that assembles it into the final program. + Module source code files ------------------------ diff --git a/docs/source/index.rst b/docs/source/index.rst index 643bbf1a7..bd5d180fc 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -38,7 +38,7 @@ Design principles - Provide a convenient edit/compile/run cycle by being able to directly launch the compiled program in an emulator and provide debugging information to the emulator. - The compiler outputs a regular 6502 assembly code file, it doesn't assemble this itself. - A third party cross-assembler tool is used to do this final step. + The '64tass' third party cross-assembler tool is used to do this final step. - Goto is considered harmful, but not here; arbitrary control flow jumps are allowed. - No complicated error handling or overflow checks that would slow things down. @@ -46,8 +46,9 @@ Design principles Required tools -------------- +`64tass `_ - cross assembler + @TODO -- 64tass cross-assembler? - java? - kotlin? diff --git a/docs/source/programming.rst b/docs/source/programming.rst index f1cfc81ed..66d508d95 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -166,7 +166,7 @@ Integers Integers are 8 or 16 bit numbers and can be written in normal decimal notation, in hexadecimal and in binary notation. -@todo right now only unsinged integers are supported (>=0) +@todo right now only unsinged integers are supported (0-255 for byte types, 0-65535 for word types) Strings @@ -217,12 +217,11 @@ The resulting value is simply a 16 bit word. Example:: AX = #somevar - **Indirect addressing:** -@todo +@todo ??? **Indirect addressing in jumps:** -@todo +@todo ??? For an indirect ``goto`` statement, the compiler will issue the 6502 CPU's special instruction (``jmp`` indirect). A subroutine call (``jsr`` indirect) is emitted using a couple of instructions. @@ -280,22 +279,24 @@ Expressions ----------- In most places where a number or other value is expected, you can use just the number, or a full constant expression. -The expression is parsed and evaluated by Python itself at compile time, and the (constant) resulting value is used in its place. -Ofcourse the special il65 syntax for hexadecimal numbers (``$xxxx``), binary numbers (``%bbbbbbbb``), -and the address-of (``#xxxx``) is supported. Other than that it must be valid Python syntax. +The expression is parsed and evaluated by the compiler itself at compile time, and the (constant) resulting value is used in its place. Expressions can contain function calls to the math library (sin, cos, etc) and you can also use all builtin functions (max, avg, min, sum etc). They can also reference idendifiers defined elsewhere in your code, if this makes sense. -Arithmetic -^^^^^^^^^^ -@todo +Arithmetic and Logical expressions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Arithmetic expressions are expressions that calculate a numeric result (integer or floating point). +Many common arithmetic operators can be used and follow the regular precedence rules. +Logical expressions are expressions that calculate a boolean result, true or false +(which in IL65 will effectively be a 1 or 0 integer value). -Logical expressions -^^^^^^^^^^^^^^^^^^^ -@todo +You can use parentheses to group parts of an expresion to change the precedence. +Usually the normal precedence rules apply (``*`` goes before ``+`` etc.) but subexpressions +within parentheses will be evaluated first. So ``(4 + 8) * 2`` is 24 and not 20, +and ``(true or false) and false`` is false instead of true. Subroutines diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index cc2c4c370..140b37f56 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -227,10 +227,10 @@ type identifier type storage size example var declara ``word`` unsigned word 2 bytes = 16 bits ``word myvar = $8fee`` ``float`` floating-point 5 bytes = 40 bits ``float myvar = 1.2345`` stored in 5-byte cbm MFLPT format -``byte[x]`` byte array x bytes ``byte[4] myvar = [1, 2, 3, 4]`` -``word[x]`` word array 2*x bytes ``word[4] myvar = [1, 2, 3, 4]`` -``byte[x,y]`` byte matrix x*y bytes ``byte[40,25] myvar = @todo`` - Note: word-matrix not supported +``byte[x]`` unsigned byte array x bytes ``byte[4] myvar = [1, 2, 3, 4]`` +``word[x]`` unsigned word array 2*x bytes ``word[4] myvar = [1, 2, 3, 4]`` +``byte[x,y]`` unsigned byte matrix x*y bytes ``byte[40,25] myvar = @todo`` + word-matrix not supported ``str`` string (petscii) varies ``str myvar = "hello."`` implicitly terminated by a 0-byte ``str_p`` pascal-string (petscii) varies ``str_p myvar = "hello."`` @@ -243,6 +243,7 @@ type identifier type storage size example var declara **@todo pointers/addresses? (as opposed to normal WORDs)** + **@todo signed integers (byte and word)?** @@ -340,9 +341,9 @@ When put after a sequence type (array, string or matrix) it means to point to th .. data:: ( ... ) (precedence grouping in expressions, or subroutine parameter list) -Parentheses are used to chose the evaluation precedence in expressions. -Usually the normal precedence rules apply (``*`` goes before ``+`` etc.) but with -parentheses you can change this: ``4 + 8 * 2`` is 20, but ``(4 + 8) * 2`` is 24. +Parentheses are used to group parts of an expression to change the order of evaluation. +(the subexpression inside the parentheses will be evaluated first): +``(4 + 8) * 2`` is 24 instead of 20. Parentheses are also used in a subroutine call, they follow the name of the subroutine and contain the list of arguments to pass to the subroutine: ``big_function(1, 99)`` @@ -397,8 +398,6 @@ and not specifying a code block:: comma separated list of ":" pairs specifying the input parameters. You can omit the parameter names as long as the arguments "line up". - (actually, the Python parameter passing rules apply, so you can also mix positional - and keyword arguments, as long as the keyword arguments come last) .. data:: proc_results diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 4fc28c7f5..3cc7cfeb4 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -111,11 +111,10 @@ For:: ### Macros -@todo macros are meta-code (written in Python syntax) that actually runs in a preprecessing step -during the compilation, and produces output value that is then replaced on that point in the input source. -Allows us to create pre calculated sine tables and such. Something like:: +@todo macros are meta-code that is executed by the compiler, in a preprecessing step +during the compilation, and can produce output that is then replaced on that point in the input source. +Allows us to create pre calculated sine tables and such. - var .array sinetable ``[sin(x) * 10 for x in range(100)]`` Memory Block Operations diff --git a/il65/lib/c64lib.ill b/lib65/c64lib.ill similarity index 100% rename from il65/lib/c64lib.ill rename to lib65/c64lib.ill diff --git a/il65/lib/il65lib.ill b/lib65/il65lib.ill similarity index 100% rename from il65/lib/il65lib.ill rename to lib65/il65lib.ill diff --git a/il65/lib/mathlib.ill b/lib65/mathlib.ill similarity index 100% rename from il65/lib/mathlib.ill rename to lib65/mathlib.ill diff --git a/il65/lib/restorezp.asm b/lib65/restorezp.asm similarity index 100% rename from il65/lib/restorezp.asm rename to lib65/restorezp.asm diff --git a/il65/__init__.py b/python/il65/__init__.py similarity index 100% rename from il65/__init__.py rename to python/il65/__init__.py diff --git a/il65/__main__.py b/python/il65/__main__.py similarity index 100% rename from il65/__main__.py rename to python/il65/__main__.py diff --git a/il65/codegen/__init__.py b/python/il65/codegen/__init__.py similarity index 100% rename from il65/codegen/__init__.py rename to python/il65/codegen/__init__.py diff --git a/il65/codegen/mos6502/__init__.py b/python/il65/codegen/mos6502/__init__.py similarity index 100% rename from il65/codegen/mos6502/__init__.py rename to python/il65/codegen/mos6502/__init__.py diff --git a/il65/codegen/mos6502/assignment.py b/python/il65/codegen/mos6502/assignment.py similarity index 100% rename from il65/codegen/mos6502/assignment.py rename to python/il65/codegen/mos6502/assignment.py diff --git a/il65/codegen/mos6502/calls.py b/python/il65/codegen/mos6502/calls.py similarity index 100% rename from il65/codegen/mos6502/calls.py rename to python/il65/codegen/mos6502/calls.py diff --git a/il65/codegen/mos6502/generate.py b/python/il65/codegen/mos6502/generate.py similarity index 100% rename from il65/codegen/mos6502/generate.py rename to python/il65/codegen/mos6502/generate.py diff --git a/il65/codegen/mos6502/incrdecr.py b/python/il65/codegen/mos6502/incrdecr.py similarity index 100% rename from il65/codegen/mos6502/incrdecr.py rename to python/il65/codegen/mos6502/incrdecr.py diff --git a/il65/codegen/mos6502/variables.py b/python/il65/codegen/mos6502/variables.py similarity index 100% rename from il65/codegen/mos6502/variables.py rename to python/il65/codegen/mos6502/variables.py diff --git a/il65/codegen/shared.py b/python/il65/codegen/shared.py similarity index 100% rename from il65/codegen/shared.py rename to python/il65/codegen/shared.py diff --git a/il65/codegen/tinyvm/__init__.py b/python/il65/codegen/tinyvm/__init__.py similarity index 100% rename from il65/codegen/tinyvm/__init__.py rename to python/il65/codegen/tinyvm/__init__.py diff --git a/il65/codegen/tinyvm/generate.py b/python/il65/codegen/tinyvm/generate.py similarity index 100% rename from il65/codegen/tinyvm/generate.py rename to python/il65/codegen/tinyvm/generate.py diff --git a/il65/compile.py b/python/il65/compile.py similarity index 100% rename from il65/compile.py rename to python/il65/compile.py diff --git a/il65/constantfold.py b/python/il65/constantfold.py similarity index 100% rename from il65/constantfold.py rename to python/il65/constantfold.py diff --git a/il65/datatypes.py b/python/il65/datatypes.py similarity index 100% rename from il65/datatypes.py rename to python/il65/datatypes.py diff --git a/il65/main.py b/python/il65/main.py similarity index 100% rename from il65/main.py rename to python/il65/main.py diff --git a/il65/oldstuff/codegen.py b/python/il65/oldstuff/codegen.py similarity index 100% rename from il65/oldstuff/codegen.py rename to python/il65/oldstuff/codegen.py diff --git a/il65/optimize.py b/python/il65/optimize.py similarity index 100% rename from il65/optimize.py rename to python/il65/optimize.py diff --git a/il65/plylex.py b/python/il65/plylex.py similarity index 100% rename from il65/plylex.py rename to python/il65/plylex.py diff --git a/il65/plyparse.py b/python/il65/plyparse.py similarity index 100% rename from il65/plyparse.py rename to python/il65/plyparse.py diff --git a/mypy.ini b/python/mypy.ini similarity index 100% rename from mypy.ini rename to python/mypy.ini diff --git a/requirements.txt b/python/requirements.txt similarity index 100% rename from requirements.txt rename to python/requirements.txt diff --git a/run_profile.py b/python/run_profile.py similarity index 100% rename from run_profile.py rename to python/run_profile.py diff --git a/setup.cfg b/python/setup.cfg similarity index 100% rename from setup.cfg rename to python/setup.cfg diff --git a/tests/__init__.py b/python/tests/__init__.py similarity index 100% rename from tests/__init__.py rename to python/tests/__init__.py diff --git a/tests/test_codegen_mos6502.py b/python/tests/test_codegen_mos6502.py similarity index 100% rename from tests/test_codegen_mos6502.py rename to python/tests/test_codegen_mos6502.py diff --git a/tests/test_core.py b/python/tests/test_core.py similarity index 100% rename from tests/test_core.py rename to python/tests/test_core.py diff --git a/tests/test_optimizer.py b/python/tests/test_optimizer.py similarity index 100% rename from tests/test_optimizer.py rename to python/tests/test_optimizer.py diff --git a/tests/test_parser.py b/python/tests/test_parser.py similarity index 100% rename from tests/test_parser.py rename to python/tests/test_parser.py diff --git a/tests/test_vardef.py b/python/tests/test_vardef.py similarity index 100% rename from tests/test_vardef.py rename to python/tests/test_vardef.py diff --git a/tests/test_vmcore.py b/python/tests/test_vmcore.py similarity index 100% rename from tests/test_vmcore.py rename to python/tests/test_vmcore.py diff --git a/tests/test_zp.py b/python/tests/test_zp.py similarity index 100% rename from tests/test_zp.py rename to python/tests/test_zp.py diff --git a/tinyvm/__init__.py b/python/tinyvm/__init__.py similarity index 100% rename from tinyvm/__init__.py rename to python/tinyvm/__init__.py diff --git a/tinyvm/core.py b/python/tinyvm/core.py similarity index 100% rename from tinyvm/core.py rename to python/tinyvm/core.py diff --git a/tinyvm/examples/printiovm.txt b/python/tinyvm/examples/printiovm.txt similarity index 100% rename from tinyvm/examples/printiovm.txt rename to python/tinyvm/examples/printiovm.txt diff --git a/tinyvm/examples/testvm-timer.txt b/python/tinyvm/examples/testvm-timer.txt similarity index 100% rename from tinyvm/examples/testvm-timer.txt rename to python/tinyvm/examples/testvm-timer.txt diff --git a/tinyvm/examples/testvm.txt b/python/tinyvm/examples/testvm.txt similarity index 100% rename from tinyvm/examples/testvm.txt rename to python/tinyvm/examples/testvm.txt diff --git a/tinyvm/main.py b/python/tinyvm/main.py similarity index 100% rename from tinyvm/main.py rename to python/tinyvm/main.py diff --git a/tinyvm/parse.py b/python/tinyvm/parse.py similarity index 100% rename from tinyvm/parse.py rename to python/tinyvm/parse.py diff --git a/tinyvm/program.py b/python/tinyvm/program.py similarity index 100% rename from tinyvm/program.py rename to python/tinyvm/program.py diff --git a/tinyvm/vm.py b/python/tinyvm/vm.py similarity index 100% rename from tinyvm/vm.py rename to python/tinyvm/vm.py diff --git a/todo.ill b/testsource/todo.ill similarity index 100% rename from todo.ill rename to testsource/todo.ill diff --git a/todo2.ill b/testsource/todo2.ill similarity index 100% rename from todo2.ill rename to testsource/todo2.ill