aboutsummaryrefslogtreecommitdiff
path: root/parser.d
diff options
context:
space:
mode:
authormryouse2023-05-25 22:45:23 +0000
committermryouse2023-05-25 22:45:23 +0000
commit3535bfefccea789169786767ac80c54241cae019 (patch)
treeecc376d5d0effd75b31fb0a78ee55fedfc92b64a /parser.d
parent9fe6496202bd95d252ed2323a88fd24781780b64 (diff)
lambdas!
Diffstat (limited to 'parser.d')
-rw-r--r--parser.d46
1 files changed, 46 insertions, 0 deletions
diff --git a/parser.d b/parser.d
index 68f5093..e51b5e1 100644
--- a/parser.d
+++ b/parser.d
@@ -12,6 +12,7 @@ enum FormType {
NIL,
SYMBOL,
FUNC,
+ LAMBDA,
DEF,
BLOCK,
IF,
@@ -211,6 +212,21 @@ class Func : Form {
}
}
+class Lambda : Form {
+
+ Cons args;
+ Form[] lambdaBody;
+
+ this (int line) {
+ this.line = line;
+ this.type = FormType.LAMBDA;
+ }
+
+ void addToBody(Form f) {
+ this.lambdaBody ~= f;
+ }
+}
+
class Def : Form {
Symbol name;
@@ -449,6 +465,34 @@ class Parser {
return def;
}
+ Form parseLambda() {
+ // we've parsed `lambda` already
+ Form args = parseForm();
+ if (args.type != FormType.CONS && args.type != FormType.NIL) {
+ return new ParseError("func definitions expect a list of arguments", line);
+ }
+
+ Lambda lamb = new Lambda(line);
+ lamb.args = cast(Cons)args;
+
+ char next;
+ while(peekable()) {
+ next = peek();
+ if (next == ')') {
+ break;
+ }
+ lamb.addToBody(this.parseForm());
+ }
+
+ if (!peekable()) {
+ return new ParseError("unterminated lambda", line);
+ }
+
+ advance(); // consume closing paren
+
+ return lamb;
+ }
+
Form parseFunc() {
// we've parsed `func`, but not the symbol yet
Form sym = parseForm();
@@ -579,6 +623,8 @@ class Parser {
switch (s.name) {
case "func":
return parseFunc();
+ case "lambda":
+ return parseLambda();
case "def":
return parseDef();
case "block":