Skip to content

Commit 51f29d8

Browse files
committed
PiccodeClosure: Implement annonations right before the final call
1 parent 58d1ec3 commit 51f29d8

File tree

1 file changed

+52
-41
lines changed

1 file changed

+52
-41
lines changed

src/main/java/org/piccode/rt/PiccodeClosure.java

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class PiccodeClosure implements PiccodeValue {
3535
public int line, column;
3636
public Integer frame = null;
3737

38+
public List<String> annotations = new ArrayList<>();
39+
3840
public PiccodeClosure(List<Ast> params, Map<String, PiccodeValue> appliedArgs, int positionalIndex, Ast body) {
3941
this.params = params == null ? new ArrayList<>() : params;
4042
this.appliedArgs = appliedArgs;
@@ -61,6 +63,7 @@ public PiccodeValue call(PiccodeValue arg) {
6163
}
6264

6365
var result = new PiccodeClosure(params, newArgs, positionalIndex + 1, body);
66+
result.annotations = annotations;
6467
result.creator = creator;
6568
result.frame = frame;
6669
result.callSite = callSite;
@@ -105,6 +108,7 @@ public PiccodeValue callNamed(String name, PiccodeValue arg) {
105108
newArgs.put(name, arg);
106109

107110
var result = new PiccodeClosure(params, newArgs, positionalIndex + 1, body);
111+
result.annotations = annotations;
108112
result.creator = creator;
109113
result.frame = frame;
110114
result.callSite = callSite;
@@ -125,48 +129,56 @@ public PiccodeValue evaluateIfReady() {
125129
}
126130
}
127131
}
128-
var ctx = frame == null
129-
? Context.top
130-
: Context.getContextAt(frame);
131-
ctx.pushStackFrame(creator);
132-
for (Ast param : params) {
133-
PiccodeValue val = param instanceof Arg arg
134-
? appliedArgs.getOrDefault(
135-
arg.name,
136-
arg.def_val != null ? arg.def_val.execute(frame) : null
137-
) : param.execute(frame);
132+
return Ast.safeExecute(frame, creator, ($_unused_$) -> {
133+
for (Ast param : params) {
134+
var ctx = frame == null
135+
? Context.top
136+
: Context.getContextAt(frame);
137+
138+
139+
PiccodeValue val = param instanceof Arg arg
140+
? appliedArgs.getOrDefault(
141+
arg.name,
142+
arg.def_val != null ? arg.def_val.execute(frame) : null
143+
) : param.execute(frame);
138144

139-
if (param instanceof Arg arg) {
140-
if (arg.export && !(val instanceof PiccodeObject)) {
141-
throw new PiccodeException(param.file, param.line, param.column, "Cannot export fields of a value that is not an object. Found type " + Chalk.on(val.type()).red());
142-
} else if (arg.export && val instanceof PiccodeObject obj) {
143-
for (var kv : obj.obj.entrySet()) {
144-
var name = kv.getKey();
145-
var value = kv.getValue();
146-
ctx.putLocal(name, value);
145+
if (param instanceof Arg arg) {
146+
if (arg.export && !(val instanceof PiccodeObject)) {
147+
throw new PiccodeException(param.file, param.line, param.column, "Cannot export fields of a value that is not an object. Found type " + Chalk.on(val.type()).red());
148+
} else if (arg.export && val instanceof PiccodeObject obj) {
149+
for (var kv : obj.obj.entrySet()) {
150+
var name = kv.getKey();
151+
var value = kv.getValue();
152+
ctx.putLocal(name, value);
153+
}
154+
} else {
155+
ctx.putLocal(arg.name, val);
147156
}
148-
} else {
149-
ctx.putLocal(arg.name, val);
150157
}
151158
}
152-
}
153159

154-
try {
155-
var result = body.execute(frame);
156-
ctx.dropStackFrame();
157-
158-
return result;
159-
} catch (PiccodeReturnException ret) {
160-
ctx.dropStackFrame();
161-
return ret.value;
162-
} catch (StackOverflowError se) {
163-
ctx.dropStackFrame();
164-
var err = new PiccodeException(callSiteFile, callSite.line, callSite.col, "Stack overflow");
165-
err.frame = frame;
166-
var note = new PiccodeException(file, line, column, "Stack overflow error most likely occured when you called the function below. ");
167-
err.addNote(note);
168-
throw err;
169-
}
160+
161+
try {
162+
if (!annotations.isEmpty()) {
163+
for (var annotation: annotations) {
164+
if (!Context.hasAnnotation(annotation)) {
165+
throw new PiccodeException(file, line, column, "Annotation `" + Chalk.on(annotation).red() + "` does not exist.");
166+
}
167+
// TODO: Allow mutiple nested annotations
168+
var fx = Context.getAnnotation(annotation);
169+
return fx.apply(frame, body);
170+
}
171+
}
172+
var result = body.execute(frame);
173+
return result;
174+
} catch (StackOverflowError se) {
175+
var err = new PiccodeException(callSiteFile, callSite.line, callSite.col, "Stack overflow");
176+
err.frame = frame;
177+
var note = new PiccodeException(file, line, column, "Stack overflow error most likely occured when you called the function below. ");
178+
err.addNote(note);
179+
throw err;
180+
}
181+
});
170182
}
171183

172184
@Override
@@ -212,15 +224,14 @@ private void createWhenExpression(Integer frame) {
212224
cases.add(when);
213225
}
214226

215-
216227
var args = clause.getArgs();
217228
var cond = args.size() == 1 ? args.getFirst() : new TupleAst(args);
218-
229+
219230
var errNode = new ErrorNodeExpr("Inexhaustive when expression: no pattern matched: when " + cond + " { ... }");
220231
errNode.file = file;
221232
errNode.line = line;
222233
errNode.column = column;
223-
234+
224235
var generalCaseBody = isMatched(clause.body, cases)
225236
? errNode
226237
: clause.body;
@@ -290,7 +301,7 @@ private void computeStableClause() {
290301
newParams.addLast(arg);
291302
}
292303
}
293-
}
304+
}
294305

295306
clauses.add(new ClauseAst(params, body));
296307
params = newParams;

0 commit comments

Comments
 (0)