Skip to content

Commit 18e5172

Browse files
committed
MAL implementation in Modula-2.
This implementation uses the GNU Modula2 compiler and it runs all sets and test suites. Dockerfile is availabe for systems without a gm2 compiler. The implemention was harder than I expected. I worked with modula-2 twice in my early jobs. And I have fond memories of it. This work has also served as a reminder of those early days when everything was yet to be built, and we reinvented the wheel continously. Summary ------- * All steps implemented, Pass all tests. * Do not use modula2 ALLOCATE, details below. * Do not have a garbage collector. GM2 Compiler ------------ Having a GM2 compiler was the key enabler of this implementation, furthermore it includes the PIM and ISO libraries. I realized there was a modula-2 compiler two years ago, despite it have been available for more than ten years. Knowing the compiler was available, the only remaining challenge was finding enough time to dedicate to the project. GM2 ALLOCATE/NEW ---------------- 50% of the project was fighting with the ALLOCATE/NEW to reserve memory. It's slow. ALLOCATE / NEW also tracks every reserved object in a list. Some of the steps make heavy use of dynamic memory, and the ALLOCATE is really slow due to the objet tracking management. By step 5 i give up, and started using malloc. It was soo slow that the TCO test timeout despite the tail call optimization was workin was working.. Garbage collector ----------------- I intend to implement a Garbage Collector (Mark-and-Sweep or Cheney-style copying), if I can allocate additional time. Run Suite --------- $ make "docker-build^modula2" $ make DOCKERIZE=1 "test^modula2" Thanks ------ Obviously this implementation wasn't posible without the work of Niklaus Wirth and Gaius Mulley.
1 parent 2bbfaa5 commit 18e5172

28 files changed

+9409
-1
lines changed

Makefile.impls

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ wasm_MODE = wasmtime
3535
IMPLS = ada ada.2 awk bash basic bbc-basic c c.2 chuck clojure coffee common-lisp cpp crystal cs d dart \
3636
elisp elixir elm erlang es6 factor fantom fennel forth fsharp go groovy gnu-smalltalk \
3737
guile hare haskell haxe hy io janet java java-truffle js jq julia kotlin latex3 livescript logo lua make mal \
38-
matlab miniMAL nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \
38+
matlab miniMAL modula2 nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \
3939
plsql powershell prolog ps purs python2 python3 r racket rexx rpython ruby ruby.2 rust scala scheme skew sml \
4040
swift swift3 swift4 swift6 tcl ts vala vb vbs vhdl vimscript wasm wren yorick xslt zig
4141

@@ -157,6 +157,7 @@ make_STEP_TO_PROG = impls/make/$($(1)).mk
157157
mal_STEP_TO_PROG = impls/mal/$($(1)).mal
158158
matlab_STEP_TO_PROG = impls/matlab/$($(1)).m
159159
miniMAL_STEP_TO_PROG = impls/miniMAL/$($(1)).json
160+
modula2_STEP_TO_PROG = impls/modula2/$($(1))
160161
nasm_STEP_TO_PROG = impls/nasm/$($(1))
161162
nim_STEP_TO_PROG = impls/nim/$($(1))
162163
objc_STEP_TO_PROG = impls/objc/$($(1))

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ FAQ](docs/FAQ.md) where I attempt to answer some common questions.
9797
| [mal itself](#mal) | [Joel Martin](https://github.com/kanaka) |
9898
| [MATLAB](#matlab-gnu-octave-and-matlab) (GNU Octave & MATLAB) | [Joel Martin](https://github.com/kanaka) |
9999
| [miniMAL](#minimal) ([Repo](https://github.com/kanaka/miniMAL), [Demo](https://kanaka.github.io/miniMAL/)) | [Joel Martin](https://github.com/kanaka) |
100+
| [Modula2](#Modula2) | [Jose Rubio](https://github.com/zawaza-blog) |
100101
| [NASM](#nasm) | [Ben Dudson](https://github.com/bendudson) |
101102
| [Nim](#nim-104) | [Dennis Felsing](https://github.com/def-) |
102103
| [Object Pascal](#object-pascal) | [Joel Martin](https://github.com/kanaka) |
@@ -764,6 +765,16 @@ cd impls/make
764765
make -f stepX_YYY.mk
765766
```
766767

768+
### Modula2
769+
770+
The Modula-2 implementation of mal is written with the GNU Modula-2.
771+
It has been tested with Ubuntu 24 and gm2 13.3
772+
773+
```
774+
make "docker-build^modula2"
775+
make DOCKERIZE=1 "test^modula2"
776+
```
777+
767778
### NASM
768779

769780
The NASM implementation of mal is written for x86-64 Linux, and has been tested

impls/modula2/Core.def

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
DEFINITION MODULE Core;
2+
3+
(* MAL Core Functions - Definition Module *)
4+
5+
FROM Types IMPORT MalVal;
6+
FROM Env IMPORT Env;
7+
8+
(* Evaluator procedure type - for passing EVAL to Core *)
9+
TYPE
10+
EvalProc = PROCEDURE(MalVal, Env): MalVal;
11+
12+
(* Arithmetic operations *)
13+
PROCEDURE Add(args: MalVal): MalVal;
14+
PROCEDURE Sub(args: MalVal): MalVal;
15+
PROCEDURE Mul(args: MalVal): MalVal;
16+
PROCEDURE Div(args: MalVal): MalVal;
17+
18+
(* Comparison operations *)
19+
PROCEDURE Equal(args: MalVal): MalVal;
20+
PROCEDURE LessThan(args: MalVal): MalVal;
21+
PROCEDURE LessThanOrEqual(args: MalVal): MalVal;
22+
PROCEDURE GreaterThan(args: MalVal): MalVal;
23+
PROCEDURE GreaterThanOrEqual(args: MalVal): MalVal;
24+
25+
(* Logical operations *)
26+
PROCEDURE NotFn(args: MalVal): MalVal;
27+
28+
(* List operations *)
29+
PROCEDURE MakeList(args: MalVal): MalVal;
30+
PROCEDURE MakeVector(args: MalVal): MalVal;
31+
PROCEDURE MakeHashMap(args: MalVal): MalVal;
32+
PROCEDURE NormalizeHashMap(hmap: MalVal): MalVal;
33+
PROCEDURE GetFn(args: MalVal): MalVal;
34+
PROCEDURE AssocFn(args: MalVal): MalVal;
35+
PROCEDURE ContainsFn(args: MalVal): MalVal;
36+
PROCEDURE DissocFn(args: MalVal): MalVal;
37+
PROCEDURE KeysFn(args: MalVal): MalVal;
38+
PROCEDURE ValsFn(args: MalVal): MalVal;
39+
PROCEDURE IsListFn(args: MalVal): MalVal;
40+
PROCEDURE IsEmptyFn(args: MalVal): MalVal;
41+
PROCEDURE CountFn(args: MalVal): MalVal;
42+
PROCEDURE ConsFn(args: MalVal): MalVal;
43+
PROCEDURE ConcatFn(args: MalVal): MalVal;
44+
PROCEDURE VecFn(args: MalVal): MalVal;
45+
PROCEDURE NthFn(args: MalVal): MalVal;
46+
PROCEDURE FirstFn(args: MalVal): MalVal;
47+
PROCEDURE RestFn(args: MalVal): MalVal;
48+
49+
(* Quasiquote support *)
50+
PROCEDURE Quasiquote(ast: MalVal): MalVal;
51+
52+
(* Atom operations *)
53+
PROCEDURE AtomFn(args: MalVal): MalVal;
54+
PROCEDURE IsAtomFn(args: MalVal): MalVal;
55+
PROCEDURE DerefFn(args: MalVal): MalVal;
56+
PROCEDURE ResetFn(args: MalVal): MalVal;
57+
PROCEDURE SwapFn(args: MalVal): MalVal;
58+
59+
(* Macro operations *)
60+
PROCEDURE IsMacroFn(args: MalVal): MalVal;
61+
62+
(* Exception operations *)
63+
PROCEDURE ThrowFn(args: MalVal): MalVal;
64+
65+
(* Type predicates *)
66+
PROCEDURE NilPredFn(args: MalVal): MalVal;
67+
PROCEDURE TruePredFn(args: MalVal): MalVal;
68+
PROCEDURE FalsePredFn(args: MalVal): MalVal;
69+
PROCEDURE SymbolPredFn(args: MalVal): MalVal;
70+
PROCEDURE KeywordPredFn(args: MalVal): MalVal;
71+
PROCEDURE SequentialPredFn(args: MalVal): MalVal;
72+
PROCEDURE VectorPredFn(args: MalVal): MalVal;
73+
PROCEDURE MapPredFn(args: MalVal): MalVal;
74+
75+
(* Symbol and keyword constructors *)
76+
PROCEDURE SymbolFn(args: MalVal): MalVal;
77+
PROCEDURE KeywordFn(args: MalVal): MalVal;
78+
79+
(* Functional programming *)
80+
PROCEDURE ApplyFn(args: MalVal): MalVal;
81+
PROCEDURE MapFn(args: MalVal): MalVal;
82+
83+
(* Function parameter binding *)
84+
PROCEDURE BindFunctionParams(params: MalVal; args: MalVal; env: Env): BOOLEAN;
85+
86+
(* String/IO operations *)
87+
PROCEDURE ReadStringFn(args: MalVal): MalVal;
88+
PROCEDURE SlurpFn(args: MalVal): MalVal;
89+
90+
(* Evaluation *)
91+
PROCEDURE EvalFn(args: MalVal): MalVal;
92+
93+
(* Printing operations *)
94+
PROCEDURE PrStrFn(args: MalVal): MalVal;
95+
PROCEDURE StrFn(args: MalVal): MalVal;
96+
PROCEDURE PrnFn(args: MalVal): MalVal;
97+
PROCEDURE PrintlnFn(args: MalVal): MalVal;
98+
99+
(* REPL environment initialization *)
100+
PROCEDURE SetEvaluator(evalProc: EvalProc);
101+
PROCEDURE InitReplEnv(argc: CARDINAL): Env;
102+
103+
END Core.

0 commit comments

Comments
 (0)