mirror of
https://github.com/irmen/prog8.git
synced 2024-11-23 07:32:10 +00:00
doc updates
This commit is contained in:
parent
91d9559f79
commit
4fd14f1366
@ -143,6 +143,7 @@ Design principles and features
|
||||
still able to directly use memory addresses, CPU registers and ROM subroutines,
|
||||
and inline assembly to have full control when every cycle or byte matters
|
||||
- Arbitrary number of subroutine parameters (constrained only by available memory)
|
||||
- Nested subroutines can access variables from outer scopes, this avoids the need and overhead to pass everything via parameters
|
||||
- Complex nested expressions are possible
|
||||
- Values are typed. Types supported include signed and unsigned bytes and words, arrays, strings and floats.
|
||||
- No dynamic memory allocation or sizing! All variables stay fixed size as determined at compile time.
|
||||
@ -158,7 +159,7 @@ Design principles and features
|
||||
- The compiler tries to optimize the program and generated code, but hand-tuning of the
|
||||
performance or space-critical parts will likely still be required. This is supported by
|
||||
the ability to easily write embedded assembly code directly in the program source code.
|
||||
- There are many built-in functions such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse``
|
||||
- There are many built-in functions, such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse``
|
||||
|
||||
|
||||
.. _requirements:
|
||||
@ -167,26 +168,25 @@ Required tools
|
||||
--------------
|
||||
|
||||
`64tass <https://sourceforge.net/projects/tass64/>`_ - cross assembler. Install this on your shell path.
|
||||
A recent .exe version of this tool for Windows can be obtained from my `clone <https://github.com/irmen/64tass/releases>`_ of this project.
|
||||
For other platforms it is very easy to compile it yourself (make ; make install).
|
||||
It's very easy to compile yourself.
|
||||
A recent precompiled .exe for Windows can be obtained from my `clone <https://github.com/irmen/64tass/releases>`_ of this project.
|
||||
|
||||
A **Java runtime (jre or jdk), version 8 or newer** is required to run the packaged compiler.
|
||||
If you're scared of Oracle's licensing terms, most Linux distributions ship OpenJDK instead
|
||||
and for Windows it's possible to get that as well. Check out `AdoptOpenJDK <https://adoptopenjdk.net/>`_ for
|
||||
downloads.
|
||||
A **Java runtime (jre or jdk), version 8 or newer** is required to run the prog8 compiler itself.
|
||||
If you're scared of Oracle's licensing terms, most Linux distributions ship OpenJDK instead.
|
||||
Fnd for Windows it's possible to get that as well. Check out `AdoptOpenJDK <https://adoptopenjdk.net/>`_ .
|
||||
|
||||
Finally: a **C-64 emulator** (or a real C-64 ofcourse) to run the programs on. The compiler assumes the presence
|
||||
of the `Vice emulator <http://vice-emu.sourceforge.net/>`_.
|
||||
Finally: a **C-64 emulator** (or a real C-64 ofcourse) can be nice to test and run your programs on.
|
||||
The compiler assumes the presence of the `Vice emulator <http://vice-emu.sourceforge.net/>`_.
|
||||
|
||||
.. important::
|
||||
**Building the compiler itself:** (*Only needed if you have not downloaded a pre-built 'fat-jar'*)
|
||||
|
||||
(re)building the compiler itself requires a recent Kotlin SDK.
|
||||
The compiler is developed using the `IntelliJ IDEA <https://www.jetbrains.com/idea/>`_
|
||||
IDE from Jetbrains, with the Kotlin plugin (free community edition of this IDE is available).
|
||||
But a bare Kotlin SDK installation should work just as well.
|
||||
(Re)building the compiler itself requires a recent Kotlin SDK.
|
||||
The compiler is developed using `IntelliJ IDEA <https://www.jetbrains.com/idea/>`_ ,
|
||||
but only a Kotlin SDK installation should work as well, because the gradle tool is
|
||||
used to compile everything from the commandline.
|
||||
|
||||
Instructions on how to obtain a working compiler are in :ref:`building_compiler`.
|
||||
Instructions on how to obtain a prebuilt compiler are in :ref:`building_compiler`.
|
||||
|
||||
|
||||
.. toctree::
|
||||
|
@ -12,57 +12,56 @@ Elements of a program
|
||||
---------------------
|
||||
|
||||
Program
|
||||
Consists of one or more *modules*.
|
||||
Consists of one or more *modules*.
|
||||
|
||||
Module
|
||||
A file on disk with the ``.p8`` suffix. It contains *directives* and *code blocks*.
|
||||
Whitespace and indentation in the source code are arbitrary and can be tabs or spaces or both.
|
||||
You can also add *comments* to the source code.
|
||||
One moudule file can *import* others, and also import *library modules*.
|
||||
A file on disk with the ``.p8`` suffix. It can contain *directives* and *code blocks*.
|
||||
Whitespace and indentation in the source code are arbitrary and can be mixed tabs or spaces.
|
||||
A module file can *import* other modules, including *library modules*.
|
||||
|
||||
Comments
|
||||
Everything after a semicolon ``;`` is a comment and is ignored by the compiler.
|
||||
If the whole line is just a comment, it will be copied into the resulting assembly source code.
|
||||
This makes it easier to understand and relate the generated code. Examples::
|
||||
|
||||
A = 42 ; set the initial value to 42
|
||||
; next is the code that...
|
||||
Everything after a semicolon ``;`` is a comment and is ignored by the compiler.
|
||||
If the whole line is just a comment, this line will be copied into the resulting assembly source code for reference.
|
||||
|
||||
Directive
|
||||
These are special instructions for the compiler, to change how it processes the code
|
||||
and what kind of program it creates. A directive is on its own line in the file, and
|
||||
starts with ``%``, optionally followed by some arguments.
|
||||
These are special instructions for the compiler, to change how it processes the code
|
||||
and what kind of program it creates. A directive is on its own line in the file, and
|
||||
starts with ``%``, optionally followed by some arguments.
|
||||
|
||||
Code block
|
||||
A block of actual program code. It defines a *scope* (also known as 'namespace') and
|
||||
can contain Prog8 *code*, *variable declarations* and *subroutines*.
|
||||
More details about this below: :ref:`blocks`.
|
||||
A block of actual program code. It has a starting address in memory,
|
||||
and defines a *scope* (also known as 'namespace').
|
||||
It contains variables and subroutines.
|
||||
More details about this below: :ref:`blocks`.
|
||||
|
||||
Variable declarations
|
||||
The data that the code works on is stored in variables ('named values that can change').
|
||||
The compiler allocates the required memory for them.
|
||||
There is *no dynamic memory allocation*. The storage size of all variables
|
||||
is fixed and is determined at compile time.
|
||||
Variable declarations tend to appear at the top of the code block that uses them.
|
||||
They define the name and type of the variable, and its initial value.
|
||||
Prog8 supports a small list of data types, including special 'memory mapped' types
|
||||
that don't allocate storage but instead point to a fixed location in the address space.
|
||||
The data that the code works on is stored in variables ('named values that can change').
|
||||
The compiler allocates the required memory for them.
|
||||
There is *no dynamic memory allocation*. The storage size of all variables
|
||||
is fixed and is determined at compile time.
|
||||
Variable declarations tend to appear at the top of the code block that uses them.
|
||||
They define the name and type of the variable, and its initial value.
|
||||
Prog8 supports a small list of data types, including special 'memory mapped' types
|
||||
that don't allocate storage but instead point to a fixed location in the address space.
|
||||
|
||||
Code
|
||||
These are the instructions that make up the program's logic. There are different kinds of instructions
|
||||
('statements' is a better name):
|
||||
These are the instructions that make up the program's logic.
|
||||
Code can only occur inside a subroutine.
|
||||
There are different kinds of instructions ('statements' is a better name) such as:
|
||||
|
||||
- value assignment
|
||||
- looping (for, while, repeat, unconditional jumps)
|
||||
- conditional execution (if - then - else, when, and conditional jumps)
|
||||
- subroutine calls
|
||||
- label definition
|
||||
- value assignment
|
||||
- looping (for, while, repeat, unconditional jumps)
|
||||
- conditional execution (if - then - else, when, and conditional jumps)
|
||||
- subroutine calls
|
||||
- label definition
|
||||
|
||||
Subroutine
|
||||
Defines a piece of code that can be called by its name from different locations in your code.
|
||||
It accepts parameters and can return a value (optional).
|
||||
It can define its own variables, and it is even possible to define subroutines nested inside other subroutines.
|
||||
Their contents is scoped accordingly.
|
||||
Nested subroutines can access the variables from outer scopes.
|
||||
This removes the need and overhead to pass everything via parameters.
|
||||
|
||||
Label
|
||||
This is a named position in your code where you can jump to from another place.
|
||||
@ -90,16 +89,20 @@ Scope
|
||||
Blocks, Scopes, and accessing Symbols
|
||||
-------------------------------------
|
||||
|
||||
**Blocks** are the top level separate pieces of code and data of your program. They are combined
|
||||
into a single output program. No code or data can occur outside a block. Here's an example::
|
||||
**Blocks** are the top level separate pieces of code and data of your program. They have a
|
||||
starting address in memory and will be combined together into a single output program.
|
||||
They can only contain *directives*, *variable declarations*, *subroutines* and *inline assembly code*.
|
||||
Your actual program code can only exist inside these subroutines.
|
||||
(except the occasional inline assembly)
|
||||
|
||||
main $c000 {
|
||||
; this is code inside the block...
|
||||
}
|
||||
Here's an example::
|
||||
|
||||
main $c000 {
|
||||
; this is code inside the block...
|
||||
}
|
||||
|
||||
The name of a block must be unique in your entire program.
|
||||
Also be careful when importing other modules; blocks in your own code cannot have
|
||||
Be careful when importing other modules; blocks in your own code cannot have
|
||||
the same name as a block defined in an imported module or library.
|
||||
|
||||
If you omit both the name and address, the entire block is *ignored* by the compiler (and a warning is displayed).
|
||||
@ -109,7 +112,7 @@ want to work on later, because the contents of the ignored block are not fully p
|
||||
The address can be used to place a block at a specific location in memory.
|
||||
Usually it is omitted, and the compiler will automatically choose the location (usually immediately after
|
||||
the previous block in memory).
|
||||
The address must be >= ``$0200`` (because ``$00``--``$ff`` is the ZP and ``$100``--``$200`` is the cpu stack).
|
||||
It must be >= ``$0200`` (because ``$00``--``$ff`` is the ZP and ``$100``--``$1ff`` is the cpu stack).
|
||||
|
||||
|
||||
.. _scopes:
|
||||
@ -133,14 +136,13 @@ Scopes are created using either of these two statements:
|
||||
- subroutines (nested named scope)
|
||||
|
||||
.. note::
|
||||
In contrast to many other programming languages, a new scope is *not* created inside
|
||||
Unlike many other programming languages, a new scope is *not* created inside
|
||||
for, while and repeat statements, nor for the if statement and branching conditionals.
|
||||
This is a bit restrictive because you have to think harder about what variables you
|
||||
want to use inside a subroutine. But it is done precisely for this reason; memory in the
|
||||
target system is very limited and it would be a waste to allocate a lot of variables.
|
||||
|
||||
Right now the prog8 compiler is not advanced enough to be able to 'share' or 'overlap'
|
||||
variables intelligently by itself. So for now, it's something the programmer has to think about.
|
||||
This can be a bit restrictive because as a programmer you have to think harder about what variables you
|
||||
want to use inside a subroutine. But it is done precisely for this reason: memory in prog8's
|
||||
target systems is usually very limited and it would be a waste to allocate a lot of variables.
|
||||
The prog8 compiler is not yet advanced enough to be able to share or overlap
|
||||
variables intelligently. So for now that is something the programmer has to think about.
|
||||
|
||||
|
||||
Program Start and Entry Point
|
||||
@ -159,12 +161,12 @@ taking no parameters and having no return value.
|
||||
|
||||
As any subroutine, it has to end with a ``return`` statement (or a ``goto`` call)::
|
||||
|
||||
main {
|
||||
sub start () {
|
||||
; program entrypoint code here
|
||||
return
|
||||
}
|
||||
}
|
||||
main {
|
||||
sub start () {
|
||||
; program entrypoint code here
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
The ``main`` module is always relocated to the start of your programs
|
||||
@ -175,7 +177,6 @@ calls with the SYS statement.
|
||||
|
||||
|
||||
|
||||
|
||||
Variables and values
|
||||
--------------------
|
||||
|
||||
|
@ -172,13 +172,13 @@ Code blocks
|
||||
-----------
|
||||
|
||||
A named block of actual program code. Itefines a *scope* (also known as 'namespace') and
|
||||
can contain Prog8 *code*, *directives*, *variable declarations* and *subroutines*::
|
||||
can only contain *directives*, *variable declarations*, *subroutines* or *inline assembly*::
|
||||
|
||||
<blockname> [<address>] {
|
||||
<directives>
|
||||
<variables>
|
||||
<statements>
|
||||
<subroutines>
|
||||
<inline asm>
|
||||
}
|
||||
|
||||
The <blockname> must be a valid identifier.
|
||||
@ -191,7 +191,6 @@ Also read :ref:`blocks`. Here is an example of a code block, to be loaded at ``
|
||||
}
|
||||
|
||||
|
||||
|
||||
Labels
|
||||
------
|
||||
|
||||
|
@ -11,7 +11,7 @@ Memory Block Operations integrated in language?
|
||||
array/string memory block operations?
|
||||
|
||||
- vector inc/dec/add/sub/mul/div...? (on array or string):
|
||||
arrayvar++ / arrayvar-- / arrayvar += 2 / arrayvar -= 2 / arrayvar *= 3 / arrayvar /= 3
|
||||
``arrayvar++ / arrayvar-- / arrayvar += 2 / arrayvar -= 2 / arrayvar *= 3 / arrayvar /= 3``
|
||||
|
||||
- array operations
|
||||
copy (from another array with the same length), shift-N(left,right), rotate-N(left,right)
|
||||
|
Loading…
Reference in New Issue
Block a user