mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
added prog8 vs other languages chapter to the manual
This commit is contained in:
parent
3f630ab1b0
commit
4cd7271e30
88
docs/source/comparing.rst
Normal file
88
docs/source/comparing.rst
Normal file
@ -0,0 +1,88 @@
|
||||
.. _comparingprog8:
|
||||
|
||||
============================
|
||||
Prog8 versus other languages
|
||||
============================
|
||||
|
||||
This chapter is meant for new Prog8 users coming with existing knowledge in another programming language such as C or Python.
|
||||
It discusses some key design aspects of Prog8 and how it differs from what you may know from those languages.
|
||||
|
||||
|
||||
The language
|
||||
------------
|
||||
- Prog8 is a structured imperative programming language. It looks like a mix of Python and C.
|
||||
- It is meant to sit well above low level assembly code, but still allows that low level access to the system it runs on.
|
||||
Via language features, or even simply by using inline hand-written assembly code.
|
||||
- Identifiers and string literals can contain non-ASCII characters so for example ``knäckebröd`` and ``見せしめ`` are valid identifiers.
|
||||
|
||||
No linker
|
||||
---------
|
||||
- Even though your programs can consist of many separate module files, the compiler always outputs a single program file. There is no separate linker step.
|
||||
Currently, it's not easily possible to integrate object files created elsewhere.
|
||||
- The prog8 compiler is self-contained in a single jar file. You do need 1 external tool namely 64tass, which performs the assembler step.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
- There are byte, word (16 bits) and float datatypes for numbers). There are no bigger integer types natively available.
|
||||
- There is no automatic type enlargement: calculations remain within the data type of the operands. Any overflow silently wraps or truncates.
|
||||
You'll have to add explicit casts to increase the size of the value if required.
|
||||
For example when adding two byte variables having values 100 and 200, the result won't be 300, because that doesn't fit in a byte. It will be 44.
|
||||
You'll have to cast one or both of the *operands* to a word type first if you want to accomodate the actual result value of 300.
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
- There is no dynamic memory management in the language; all variables are statically allocated.
|
||||
(but user written libraries are possible that provide that indirectly).
|
||||
- Variables can be declared everywhere inside the code but all variable declarations in a subroutine
|
||||
are moved to the top of the subroutine. A for loop, or if/else blocks do not introduce a new scope.
|
||||
- All variables are initialized at the start of the program. There is no random garbage in them: they are zero or any other initialization value you provide.
|
||||
- This als means you can run a Prog8 program multiple times without having to reload it from disk, unlike programs produced by most other compilers targeting these 8 bit platforms.
|
||||
|
||||
|
||||
Subroutines
|
||||
-----------
|
||||
- There is no function overloading (except for a couple of builtin functions).
|
||||
- Some subroutine types can return multiple return values, and you can multi-assign those in a single statement.
|
||||
- Because every declared variable allocates some memory, it might be beneficial to share the same variables over different subroutines
|
||||
instead of defining the same sort of variables in every subroutine.
|
||||
This reduces the memory needed for variables. A convenient way to do this is by using nested subroutines - these can easily access the
|
||||
variables declared in their parent subroutine(s).
|
||||
- Everything in prog8 is publicly accessible from everywhere else (via fully scoped names) - there is no notion of private or public symbol accessibility.
|
||||
|
||||
|
||||
Pointers
|
||||
--------
|
||||
- There is no specific pointer datatype.
|
||||
There *are* pointers however, in the form of the `uword` datatype. This can be used to point to one of the possible 65536 memory locations,
|
||||
so the value it points to is always a single byte. You have to reinterpret it manually if the object it points to is something different.
|
||||
|
||||
|
||||
Strings and Arrays
|
||||
------------------
|
||||
- these are allocated once, statically, and never resized.
|
||||
- they are mutable: you can change their contents, but always keep the original storage size in mind to avoid overwriting memory outside of the buffer.
|
||||
|
||||
|
||||
Foreign function interface (external/ROM calls)
|
||||
-----------------------------------------------
|
||||
- You can use the ``romsub`` keyword to define the call signature of foreign functions (usually ROM routines, hence the name) in a natural way.
|
||||
Calling those generates code that is as efficient or even more efficient as calling regular subroutines.
|
||||
No additional stubs are needed. (unless there is bank switching going on, but this *may* be improved in a future language version)
|
||||
|
||||
Optimizations
|
||||
-------------
|
||||
- Prog8 contains many compiler optimizations to generate efficent code, but also lacks many optimizations that modern compilers do have.
|
||||
While empirical evidence shows that Prog8 generates more efficent code than some C compilers that also target the same 8 bit systems,
|
||||
it still is limited in how sophisticated the optimizations are that it performs on your code.
|
||||
- For time critical code, it may be worth it to inspect the generated assembly code to see if you could write things differently
|
||||
to help the compiler generate more efficient code (or even replace it with hand written inline assembly altogether).
|
||||
For example, if you repeat an expression multiple times it will be evaluated every time, so maybe you should store it
|
||||
in a variable instead and reuse that variable::
|
||||
|
||||
if board[i+1]==col or board[i+1]-j==col-row or board[i+1]+j==col+row {
|
||||
...do something...
|
||||
}
|
||||
|
||||
In this example, consider storing ``board[i+1]`` in a variable first and reuse that in the expression instead.
|
@ -8,7 +8,7 @@ First, getting a working compiler
|
||||
---------------------------------
|
||||
|
||||
Before you can compile Prog8 programs, you'll have to download or build the compiler itself.
|
||||
First make sure you have installed the :ref:`requirements`.
|
||||
Then make sure you have installed the :ref:`requirements`.
|
||||
Then you can choose a few ways to get a compiler:
|
||||
|
||||
**Download an official release version from Github:**
|
||||
@ -82,26 +82,27 @@ For normal use, the ``installDist`` task should suffice and after succesful comp
|
||||
.. image:: _static/antlrparser.png
|
||||
:alt: Generating the Antlr4 parser files
|
||||
|
||||
.. _requirements:
|
||||
|
||||
What is a Prog8 "Program" anyway?
|
||||
---------------------------------
|
||||
Required additional tools
|
||||
-------------------------
|
||||
|
||||
A "complete runnable program" is a compiled, assembled, and linked together single unit.
|
||||
It contains all of the program's code and data and has a certain file format that
|
||||
allows it to be loaded directly on the target system. Prog8 currently has no built-in
|
||||
support for programs that exceed 64 Kb of memory, nor for multi-part loaders.
|
||||
`64tass <https://sourceforge.net/projects/tass64/>`_ - cross assembler. Install this program somewhere on your shell's search path.
|
||||
It's easy to compile yourself, but a recent precompiled .exe (only for Windows) can be obtained from
|
||||
`the files section <https://sourceforge.net/projects/tass64/files/binaries/>`_ in the official project on sourceforge.
|
||||
*You need at least version 1.58.0 of this assembler.*
|
||||
If you are on Linux, there's probably a "64tass" package in the repositories, but check if it is a recent enough version.
|
||||
|
||||
A **Java runtime (jre or jdk), version 11 or newer** is required to run the prog8 compiler itself.
|
||||
If you're scared of Oracle's licensing terms, get one of the versions of another vendor. Even Microsoft provides their own version.
|
||||
Other OpenJDK builds can be found at `Adoptium <https://adoptium.net/temurin/releases/?version=11>`_ .
|
||||
For MacOS you can also use the Homebrew system to install a recent version of OpenJDK.
|
||||
|
||||
For the Commodore 64, most programs will have a tiny BASIC launcher that does a SYS into the generated machine code.
|
||||
This way the user can load it as any other program and simply RUN it to start. (This is a regular ".prg" program).
|
||||
Prog8 can create those, but it is also possible to output plain binary programs
|
||||
that can be loaded into memory anywhere.
|
||||
|
||||
|
||||
Running the compiler
|
||||
--------------------
|
||||
|
||||
Make sure you have installed the :ref:`requirements`.
|
||||
|
||||
You run the Prog8 compiler on a main source code module file.
|
||||
Other modules that this code needs will be loaded and processed via imports from within that file.
|
||||
The compiler will link everything together into one output program at the end.
|
||||
@ -113,7 +114,7 @@ For normal use the compiler can be invoked with the command:
|
||||
|
||||
(Use the appropriate name and version of the jar file downloaded from one of the Git releases.
|
||||
Other ways to invoke the compiler are also available: see the introduction page about how
|
||||
to build and run the compiler yourself. The -target option is required, in this case we
|
||||
to build and run the compiler yourself. The ``-target`` option is always required, in this case we
|
||||
tell it to compile a program for the Commander X16)
|
||||
|
||||
|
||||
@ -188,7 +189,7 @@ One or more .p8 module files
|
||||
Generate an assembler listing file as well.
|
||||
|
||||
``-check``
|
||||
Quickly check the program for errors. No output will be produced.
|
||||
Quickly check the program for errors. No actual compilation will be performed.
|
||||
|
||||
``-breakinstr <instruction>``
|
||||
Also output the specified CPU instruction for a ``%breakpoint``, as well as the entry in the vice monitor list file.
|
||||
|
@ -28,6 +28,10 @@ You can compile programs for various machines:
|
||||
* Commodore PET (limited support)
|
||||
* Atari 800 XL (limited support)
|
||||
|
||||
Some language features are mentioned below, and you can also read :ref:`comparingprog8` if you
|
||||
want to quickly read about how Prog8 compares to well-known other languages.
|
||||
|
||||
|
||||
Open source Software License
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Full source code is on github: https://github.com/irmen/prog8.git
|
||||
@ -184,31 +188,14 @@ when the exact same program is compiled for the Commander X16 target, and run on
|
||||
:alt: result when run on CX16 emulator
|
||||
|
||||
|
||||
Getting the compiler
|
||||
Getting the software
|
||||
--------------------
|
||||
|
||||
Usually you just download a fat jar of an official released version, but you can also build
|
||||
it yourself from source.
|
||||
Usually you just download a fat jar of an official released compiler version, but you can also build it yourself from source.
|
||||
Detailed instructions on how to obtain a version of the compiler are in :ref:`building_compiler`.
|
||||
You can also read there what extra tools you need to get going.
|
||||
|
||||
|
||||
.. _requirements:
|
||||
|
||||
Required additional tools
|
||||
-------------------------
|
||||
|
||||
`64tass <https://sourceforge.net/projects/tass64/>`_ - cross assembler. Install this program somewhere on your shell's search path.
|
||||
It's easy to compile yourself, but a recent precompiled .exe (only for Windows) can be obtained from
|
||||
`the files section <https://sourceforge.net/projects/tass64/files/binaries/>`_ in the official project on sourceforge.
|
||||
*You need at least version 1.58.0 of this assembler.*
|
||||
If you are on Linux, there's probably a "64tass" package in the repositories, but check if it is a recent enough version.
|
||||
|
||||
A **Java runtime (jre or jdk), version 11 or newer** is required to run the prog8 compiler itself.
|
||||
If you're scared of Oracle's licensing terms, get one of the versions of another vendor. Even Microsoft provides their own version.
|
||||
Other OpenJDK builds can be found at `Adoptium <https://adoptium.net/temurin/releases/?version=11>`_ .
|
||||
For MacOS you can also use the Homebrew system to install a recent version of OpenJDK.
|
||||
|
||||
Finally: an **emulator** (or a real machine of course) to test and run your programs on.
|
||||
You may look for an **emulator** (or a real machine of course) to test and run your programs on.
|
||||
For the PET, C64 and C128 targets, the compiler assumes the presence of the `VICE emulator <http://vice-emu.sourceforge.net/>`_.
|
||||
If you're targeting the Commander X16 instead,
|
||||
download a recent emulator version for the CommanderX16, such as `x16emu <https://cx16forum.com/forum/viewforum.php?f=30>`_
|
||||
@ -221,11 +208,11 @@ If multiple options are listed above, you can select which one you want to launc
|
||||
Look in the `syntax-files <https://github.com/irmen/prog8/tree/master/syntax-files>`_ directory in the github repository to find them.
|
||||
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents of this manual:
|
||||
|
||||
comparing.rst
|
||||
compiling.rst
|
||||
programming.rst
|
||||
syntaxreference.rst
|
||||
|
@ -1,8 +1,6 @@
|
||||
.. _programstructure:
|
||||
|
||||
==========================
|
||||
What makes a Prog8 program
|
||||
==========================
|
||||
====================
|
||||
Programming in Prog8
|
||||
====================
|
||||
|
||||
This chapter describes a high level overview of the elements that make up a program.
|
||||
Details about the syntax can be found in the :ref:`syntaxreference` chapter.
|
||||
|
@ -1,13 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
Doc improvements: some short overview for people coming from other programming languages like C:
|
||||
tell something about prog8 not having function overloading, max 16 bit (u)word integer as native type (and floats sometimes),
|
||||
static variable allocations, no dynamic memory allocation in the language itself (although possible via user written libraries),
|
||||
no complex expresssion optimizations so avoid repeating costly terms like in: if board[i]==col or board[i]-i==col-row or board[i]+i==col+row {...} -> store board[i] in a (@zp) variable first and reuse that in the expression
|
||||
etc ...
|
||||
|
||||
|
||||
Improve register load order in subroutine call args assignments:
|
||||
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
|
||||
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)
|
||||
|
Loading…
x
Reference in New Issue
Block a user