added prog8 vs other languages chapter to the manual

This commit is contained in:
Irmen de Jong 2024-09-27 20:19:28 +02:00
parent 3f630ab1b0
commit 4cd7271e30
5 changed files with 116 additions and 49 deletions

88
docs/source/comparing.rst Normal file
View 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.

View File

@ -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.

View 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

View File

@ -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.

View File

@ -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!)