READMEs: added download links, reworked parts of programming guide

This commit is contained in:
slederer 2024-10-08 00:30:38 +02:00
parent 3120846f0f
commit e44b0bb33d
2 changed files with 40 additions and 19 deletions

View file

@ -20,7 +20,13 @@ Everything is open source, so you can read, understand and modify the whole syst
- compiler written in Pascal and can compile itself
- cross-compiler/-assembler can be compiled with FPC
- compiler does its own Pascal dialect with some restrictions and some extensions
- emulator available
- emulator available [here](https://gitlab.com/slederer/Tridora-CPU/-/tree/main/tridoraemu)
## Downloads
- the [source repository](https://gitlab.com/slederer/Tridora-CPU)
- the [emulator](https://git.insignificance.de/slederer/-/packages/generic/tridoraemu/0.0.1/files/2) (source and windows binary)
- the [FPGA bitstream](https://git.insignificance.de/slederer/-/packages/generic/tdr-bitstream/0.0.1/files/3) for the Arty-A7-35T board
- an [SD-card image](https://git.insignificance.de/slederer/-/packages/generic/tdr-cardimage/0.0.1/files/5)
## Demos
### Videos
@ -36,7 +42,7 @@ Everything is open source, so you can read, understand and modify the whole syst
|![image](https://insignificance.de/tridora/tdr-mandelbrot.jpg)| ![image](https://insignificance.de/tridora/tdr-ara.jpg) | ![image](https://insignificance.de/tridora/tdr-conway.jpg) |
## Supported Boards
- Arty A7 (with two PMODs for microSD cards and VGA output)
- Arty A7-35T (with two PMODs for microSD cards and VGA output)
- Nexys A7 (planned)
## Pascal Language

View file

@ -42,23 +42,12 @@ Note that the array _in_ operator will be more inefficient for larger ranges (i.
## I/O
I/O handling in Tridora Pascal is mostly compatible with other Pascal dialects when reading/writing simple variables from/to the console. There are big differences when opening/reading/writing files explicitly.
### The Problem (Rant)
(see XKCD 927)
In Wirth Pascal, I/O is woefully underspecified, and the record-oriented file I/O primitives are maybe suited for the late 1960s when Pascal was designed, but not for anything else. As a result, all Pascal dialects add their own incompatible functionality, of which the Turbo Pascal variant is probably the most common.
Generally, in Pascal you do not open files, you _reset_ or _rewrite_ them. In Wirth Pascal, you could only get already opened files at the program start (this is the parameter list of the _PROGRAM_ statement). There was no option to close a file, or to specify a filename. File I/O happened with record types and buffer variables with the _get_ and _put_ special procedures. _Rewrite_ truncates a file and prepares it for writing. _Reset_ rewinds the file pointer to the beginning of the file.
UCSD Pascal and DEC Pascal (and likely many others) added a file name parameter to _reset_ and _rewrite_, and added a _close_ special procedure. Turbo Pascal kept the original variants of _reset_ and _rewrite_ but added the _assign_ special procedure to set a file name for a file variable. They also added _close_.
File variables must have a record type, meaning that the file contains a sequence of records of that type (in binary encoding). Since in Wirth Pascal, there are no **string** variables, reading/writing strings is not very well defined, but requires a special file type called **text**. For these text files, the special procedures _read_, _readln_, _write_, _writeln_ exist to read/write scalar types while doing ASCII conversions.
In other Pascal dialects, the special procedures _read_, _readln_, _write_, _'writeln_' operate on strings by reading a line up to an end-of-line character.
I/O errors are not specified at all in Wirth Pascal. In Turbo Pascal, there is the IOResult variable which contains the error code of the last I/O operation. This is only accessible if I/O error checking has been disabled by a compiler directive. Otherwise (the default), an I/O error results in a runtime error and the program being terminated.
### Tridora's Solution
The solution in Tridora Pascal is to adopt the scheme that is found in most other programming languages:
The original Wirth Pascal has very limited file I/O capabilities. Therefore, most Pascal dialects have their own, incompatible extensions for handling file I/O.
In this tradition, Tridora Pascal obviously needs to have its own incompatible file handling.
The goal is to mostly ignore the stuff from other Pascal dialects and instead use something more intuitive and more recognizable from other programming languages:
- files are sequences of bytes
- files are used with _open_, _read_/_write_, _close_
- files can be opened in different modes
@ -74,6 +63,10 @@ The implementation also has the following properties:
- for error handling there is a function _IOResult_
- terminating the program without calling _close_ on open files will lose data
Differences from other Pascal dialects are:
- there are no _FILE OF_ types
- no _get_, _put_, _reset_, _rewrite_, _assign_
### Opening Files
There are five modes for opening files which (hopefully) cover all common use cases:
- _ModeReadonly_: file is opened only for reading, file must exist
@ -85,9 +78,11 @@ There are five modes for opening files which (hopefully) cover all common use ca
Example:
```
var f:file;
c:char;
a,b:integer;
open(f, 'myfile.text', ModeReadonly);
...
read(a,b,c);
close(f);
```
@ -97,3 +92,23 @@ file variable as a parameter. When you call _IOResult_, an error that may have o
error is not ackowledged and you do another I/O operation, a runtime error is thrown.
That means you can either write programs without checking for I/O errors, while resting assured that the program will exit if an I/O error occurs. You can also choose to check for errors with _IOResult_ if you want to avoid having runtime errors.
The function _ErrorStr_ from the standard library takes an error code as an argument and returns the corresponding textual description as a string.
Example:
```
procedure tryToReadFile;
var f:file;
begin
open(f, 'myfile.text', ModeReadonly);
if IOResult(f) <> IONoError then
begin
writeln('Could not open file: ', ErrorStr(IOResult(f)));
exit;
end;
...
close(f);
end;
```