Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions IMPLS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ IMPL:
- {IMPL: mal, MAL_IMPL: nim-mal, BUILD_IMPL: nim, NO_SELF_HOST: 1, NO_PERF: 1, SLOW: 1}
- {IMPL: matlab, NO_SELF_HOST_PERF: 1} # Octave, perf timeout
- {IMPL: miniMAL, NO_SELF_HOST_PERF: 1, SLOW: 1} # perf timeout
- {IMPL: modula2}
- {IMPL: nasm, NO_SELF_HOST: 1} # needs memory bump, then fails in step7/quasiquote
- {IMPL: nim}
- {IMPL: objpascal}
Expand Down
3 changes: 2 additions & 1 deletion Makefile.impls
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ wasm_MODE = wasmtime
IMPLS = ada ada.2 awk bash basic bbc-basic c c.2 chuck clojure coffee common-lisp cpp crystal cs d dart \
elisp elixir elm erlang es6 factor fantom fennel forth fsharp go groovy gnu-smalltalk \
guile hare haskell haxe hy io janet java java-truffle js jq julia kotlin latex3 livescript logo lua make mal \
matlab miniMAL nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \
matlab miniMAL modula2 nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \
plsql powershell prolog ps purs python2 python3 r racket rexx rpython ruby ruby.2 rust scala scheme skew sml \
swift swift3 swift4 swift6 tcl ts vala vb vbs vhdl vimscript wasm wren yorick xslt zig

Expand Down Expand Up @@ -157,6 +157,7 @@ make_STEP_TO_PROG = impls/make/$($(1)).mk
mal_STEP_TO_PROG = impls/mal/$($(1)).mal
matlab_STEP_TO_PROG = impls/matlab/$($(1)).m
miniMAL_STEP_TO_PROG = impls/miniMAL/$($(1)).json
modula2_STEP_TO_PROG = impls/modula2/$($(1))
nasm_STEP_TO_PROG = impls/nasm/$($(1))
nim_STEP_TO_PROG = impls/nim/$($(1))
objc_STEP_TO_PROG = impls/objc/$($(1))
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ FAQ](docs/FAQ.md) where I attempt to answer some common questions.
| [mal itself](#mal) | [Joel Martin](https://github.com/kanaka) |
| [MATLAB](#matlab-gnu-octave-and-matlab) (GNU Octave & MATLAB) | [Joel Martin](https://github.com/kanaka) |
| [miniMAL](#minimal) ([Repo](https://github.com/kanaka/miniMAL), [Demo](https://kanaka.github.io/miniMAL/)) | [Joel Martin](https://github.com/kanaka) |
| [Modula2](#Modula2) | [Jose Rubio](https://github.com/zawaza-blog) |
| [NASM](#nasm) | [Ben Dudson](https://github.com/bendudson) |
| [Nim](#nim-104) | [Dennis Felsing](https://github.com/def-) |
| [Object Pascal](#object-pascal) | [Joel Martin](https://github.com/kanaka) |
Expand Down Expand Up @@ -764,6 +765,16 @@ cd impls/make
make -f stepX_YYY.mk
```

### Modula2

The Modula-2 implementation of mal is written with the GNU Modula-2.
It has been tested with Ubuntu 24 and gm2 13.3

```
make "docker-build^modula2"
make DOCKERIZE=1 "test^modula2"
```

### NASM

The NASM implementation of mal is written for x86-64 Linux, and has been tested
Expand Down
2 changes: 1 addition & 1 deletion impls/mal/run
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ case ${MAL_IMPL} in
MAL_IMPL=${MAL_IMPL%%-mal}
MAL_FILE="../mal/stepA_mal.mal ${MAL_FILE}" ;;
esac
exec ./../${MAL_IMPL:-js}/run ${MAL_FILE} "${@}"
exec ./../${MAL_IMPL:-modula2}/run ${MAL_FILE} "${@}"
Copy link
Copy Markdown
Owner

@kanaka kanaka Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you accidentally changed the mal run script to use modula2 by default. You shouldn't need to do this. If you run make MAL_IMPL=modula2 test^mal that should run the tests is self-host mode using the modula2 implementation as the host implementation. The "js" here is just the fallback if you don't specify MAL_IMPL.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ops. Sorry. default MAL_IMPL has been reverted to "js".

Thanks again for your time and dedication. 😃

103 changes: 103 additions & 0 deletions impls/modula2/Core.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
DEFINITION MODULE Core;

(* MAL Core Functions - Definition Module *)

FROM Types IMPORT MalVal;
FROM Env IMPORT Env;

(* Evaluator procedure type - for passing EVAL to Core *)
TYPE
EvalProc = PROCEDURE(MalVal, Env): MalVal;

(* Arithmetic operations *)
PROCEDURE Add(args: MalVal): MalVal;
PROCEDURE Sub(args: MalVal): MalVal;
PROCEDURE Mul(args: MalVal): MalVal;
PROCEDURE Div(args: MalVal): MalVal;

(* Comparison operations *)
PROCEDURE Equal(args: MalVal): MalVal;
PROCEDURE LessThan(args: MalVal): MalVal;
PROCEDURE LessThanOrEqual(args: MalVal): MalVal;
PROCEDURE GreaterThan(args: MalVal): MalVal;
PROCEDURE GreaterThanOrEqual(args: MalVal): MalVal;

(* Logical operations *)
PROCEDURE NotFn(args: MalVal): MalVal;

(* List operations *)
PROCEDURE MakeList(args: MalVal): MalVal;
PROCEDURE MakeVector(args: MalVal): MalVal;
PROCEDURE MakeHashMap(args: MalVal): MalVal;
PROCEDURE NormalizeHashMap(hmap: MalVal): MalVal;
PROCEDURE GetFn(args: MalVal): MalVal;
PROCEDURE AssocFn(args: MalVal): MalVal;
PROCEDURE ContainsFn(args: MalVal): MalVal;
PROCEDURE DissocFn(args: MalVal): MalVal;
PROCEDURE KeysFn(args: MalVal): MalVal;
PROCEDURE ValsFn(args: MalVal): MalVal;
PROCEDURE IsListFn(args: MalVal): MalVal;
PROCEDURE IsEmptyFn(args: MalVal): MalVal;
PROCEDURE CountFn(args: MalVal): MalVal;
PROCEDURE ConsFn(args: MalVal): MalVal;
PROCEDURE ConcatFn(args: MalVal): MalVal;
PROCEDURE VecFn(args: MalVal): MalVal;
PROCEDURE NthFn(args: MalVal): MalVal;
PROCEDURE FirstFn(args: MalVal): MalVal;
PROCEDURE RestFn(args: MalVal): MalVal;

(* Quasiquote support *)
PROCEDURE Quasiquote(ast: MalVal): MalVal;

(* Atom operations *)
PROCEDURE AtomFn(args: MalVal): MalVal;
PROCEDURE IsAtomFn(args: MalVal): MalVal;
PROCEDURE DerefFn(args: MalVal): MalVal;
PROCEDURE ResetFn(args: MalVal): MalVal;
PROCEDURE SwapFn(args: MalVal): MalVal;

(* Macro operations *)
PROCEDURE IsMacroFn(args: MalVal): MalVal;

(* Exception operations *)
PROCEDURE ThrowFn(args: MalVal): MalVal;

(* Type predicates *)
PROCEDURE NilPredFn(args: MalVal): MalVal;
PROCEDURE TruePredFn(args: MalVal): MalVal;
PROCEDURE FalsePredFn(args: MalVal): MalVal;
PROCEDURE SymbolPredFn(args: MalVal): MalVal;
PROCEDURE KeywordPredFn(args: MalVal): MalVal;
PROCEDURE SequentialPredFn(args: MalVal): MalVal;
PROCEDURE VectorPredFn(args: MalVal): MalVal;
PROCEDURE MapPredFn(args: MalVal): MalVal;

(* Symbol and keyword constructors *)
PROCEDURE SymbolFn(args: MalVal): MalVal;
PROCEDURE KeywordFn(args: MalVal): MalVal;

(* Functional programming *)
PROCEDURE ApplyFn(args: MalVal): MalVal;
PROCEDURE MapFn(args: MalVal): MalVal;

(* Function parameter binding *)
PROCEDURE BindFunctionParams(params: MalVal; args: MalVal; env: Env): BOOLEAN;

(* String/IO operations *)
PROCEDURE ReadStringFn(args: MalVal): MalVal;
PROCEDURE SlurpFn(args: MalVal): MalVal;

(* Evaluation *)
PROCEDURE EvalFn(args: MalVal): MalVal;

(* Printing operations *)
PROCEDURE PrStrFn(args: MalVal): MalVal;
PROCEDURE StrFn(args: MalVal): MalVal;
PROCEDURE PrnFn(args: MalVal): MalVal;
PROCEDURE PrintlnFn(args: MalVal): MalVal;

(* REPL environment initialization *)
PROCEDURE SetEvaluator(evalProc: EvalProc);
PROCEDURE InitReplEnv(argc: CARDINAL): Env;

END Core.
Loading