[v0.0.1] Lisp on ZScript

Post your example zscripts/ACS scripts/etc here.
Forum rules
The Projects forums are only for projects. If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
User avatar
m8f
 
 
Posts: 1467
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Location: Siberia (UTC+7)

[v0.0.1] Lisp on ZScript

Post by m8f »

LispOnZscript is a toy Lisp-like language written on top of ZScript for GZDoom.

LispOnZscript is an experiment, a programming exercise, and isn’t suitable for any practical purpose. I’ll be surprised if it finds any practical purpose.

Adapted from Lisp as the Maxwell’s equations of software by Michael Nielsen.

What can LispOnZscript do?
- evaluate arithmetic expressions,
- evaluate conditional expressions (`if` and `cond`),
- define local and global variables,
- define functions and evaluate them,
- call some ZScript functions.

Take a look at expression examples from internal tests:

Code: Select all

  static tl_Test from()
  {
    let result = new("tl_Test");

    // Expression, expected evaluation result.

    result.add("0", "0");
    result.add("1", "1");
    result.add("(+ 1 2)", "3");
    result.add("(+ (* 2 3) 4)", "10");
    result.add("(quote 2)", "2");
    result.add("(quote (+ 1 2))", "(+ 1 2)");
    result.add("(atom? (+ 1 2))", "True");
    result.add("(atom? (q (+ 1 2)))", "False");
    result.add("(eq? 3 3)", "True");
    result.add("(car (quote (1 2 3)))", "1");
    result.add("(cdr (quote (1 2 3)))", "(2 3)");
    result.add("(cons 1 (quote (2 3)))", "(1 2 3)");
    result.add("(cond ((< 1 0) 2) ((< 0 1) 3))", "3");
    result.add("(null? (quote ()))", "True");
    result.add("(null? 2)", "False");
    result.add("(if True 1 2)", "1");
    result.add("(if False 1 2)", "2");
    result.add("(begin 1 2 3)", "3");
    result.add("(begin (set! abc 3) abc)", "3");
    result.add("(begin (define abc 3) abc)", "3");
    result.add("(begin (define square (lambda (x) (* x x))) (square 3))", "9");
    result.add("(begin (define cube (lambda (x) (* x (* x x)))) (cube 2))", "8");
    result.add("\"hello world\"", "\"hello world\"");

    result.add("",    "Error: unexpected EOF while reading.");
    result.add("()",  "Error: unexpected empty list.");
    result.add("(",   "Error: unmatched \"(\".");
    result.add(")",   "Error: unexpected \")\".");
    result.add("(2)", "Error: \"2\" is not a function.");
    result.add("(+ 1 2 3)",
               "Error: TODO: add support for different number of parameters.");

    result.add("player", "DoomPlayer");
    result.add("(getCharacterName player)", "DoomPlayer");
    result.add("(playerNumber player)", "0");
    result.add("(isFrozen player)", "False");
    result.add("(isFriend player player)", "True");

    return result;
  }
Things that I haven’t find ways to do to make LispOnZscript more usable:
  • Exposing ZScript class attributes. Only functions can be exposed now.
  • More generic ZScript class functions exposing. At the moment their signatures must be hardcoded.
  • Exposing ZScript structs. For example Cvar, vector. It can be done with wrapper classes, but it’s not fun.
  • Exposing ZScript enums.
LispOnZscript is a part of Doom Toolbox. Source code is here.

Return to “Script Library”