Skip to content

Commit

Permalink
New dict literals now support headers with the same syntax as blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
nick-paul committed Dec 30, 2024
1 parent 38ea07e commit ec73a33
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 309 deletions.
16 changes: 0 additions & 16 deletions base/block.aya
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,6 @@
.# Utility Functions
.#####################


.# ::list _capture_vars\n given a list of symbols, return a dict with each symbol and it's assignment
.{ Example:
aya> {1 +}:a 2:b
{1 +} 2
aya> [::a ::b].capture_vars
:{
{1 +}:a;
2:b;
}
aya> [::a ::b ::c].capture_vars
ERROR: Variable c not found
.}
{ :{1, :# {$~\:=} } }:_capture_vars;


.#? ::block .op\n return the block (allows use of (::sym or ::block) .op without type checking
{}:op;

Expand Down
2 changes: 1 addition & 1 deletion examples/quicksort.aya
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ lst qs :P
{.E1> {$\; :&V$@\< @\ :&#! @:&@.i \@.i qss @@qss JJ} ?}:qss;

.# Stack only version with no global vars
.# {.E1> {$\; :&V$@\< @\ :&#! @:&@.i \@.i _ @@_ JJ} ?} :{1, :_} :+
.# {.E1> {$\; :&V$@\< @\ :&#! @:&@.i \@.i _ @@_ JJ} ?} :{_,} :+

.# Quicksort benchmark and example output
.# aya> 10 R :# {; [100000,;.Q] {qs;}.time} :& .E \W\/
Expand Down
99 changes: 53 additions & 46 deletions src/aya/instruction/DictLiteralInstruction.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package aya.instruction;

import java.util.LinkedList;
import java.util.Queue;
import java.util.HashMap;

import aya.ReprStream;
import aya.eval.ExecutionContext;
import aya.eval.BlockEvaluator;
import aya.obj.Obj;
import aya.exceptions.runtime.EmptyStackError;
import aya.obj.block.BlockUtils;
import aya.obj.block.StaticBlock;
import aya.obj.dict.Dict;
import aya.obj.symbol.Symbol;
import aya.parser.SourceStringRef;
import aya.variable.VariableData;

/** DictFactories sit on the instruction stack. When evoked, they generate a dict
* given the current scope of variables
Expand All @@ -20,65 +20,72 @@
public class DictLiteralInstruction extends Instruction {

StaticBlock _block;
private int num_captures;
HashMap<Symbol, StaticBlock> _defaults;

public DictLiteralInstruction(SourceStringRef source, StaticBlock b) {
super(source);
this._block = b;
this.num_captures = 0;
this(source, b, null);
}

public DictLiteralInstruction(SourceStringRef source, StaticBlock b, int num_captures) {
public DictLiteralInstruction(SourceStringRef source, StaticBlock b, HashMap<Symbol, StaticBlock> defaults) {
super(source);
this._block = b;
this.num_captures = num_captures;
}

public int numCaptures() {
return num_captures;
this._defaults = defaults;
}

/** Run the dict, collect variables, return the Dict object */
public Dict getDict(ExecutionContext context, Queue<Obj> q) {
//Add the variable set to the stack
context.getVars().add(new Dict(), true);

@Override
public void execute(BlockEvaluator b) {
final VariableData vars = b.getContext().getVars();

// Add the variable set to the stack, true: capture all assignments
Dict dict_scope = new Dict();
vars.add(dict_scope, true);

//Run the blockEvaluator
BlockEvaluator evaluator = context.createEvaluator();
if (q != null) {
while (!q.isEmpty()) {
evaluator.push(q.poll());
// If there are defaults, add them to the dict scope
if (_defaults != null) {
for (Symbol var : _defaults.keySet()) {
BlockEvaluator evaluator = b.getContext().createEvaluator();
evaluator.dump(_defaults.get(var));
evaluator.eval();
dict_scope.set(var, evaluator.pop());
}
}
evaluator.dump(_block);
evaluator.eval();

// Run block in an isolated evaluator so we can copy the variables once the block is finished
BlockEvaluator evaluator = b.getContext().createEvaluator();

final int num_args = _block.getNumArgs();
final boolean has_locals = _block.hasLocals();

//Retrieve the Dict
return context.getVars().popGet();
}

@Override
public void execute(BlockEvaluator b) {
Queue<Obj> q = null;
int n = this.numCaptures();
if (n > 0) {
q = new LinkedList<Obj>();
for (int i = 0; i < n; i++) {
q.add(b.pop());
// Copy stack args into evaluator (preserve order)
if (num_args > 0) {
if (b.getStack().size() < num_args) {
throw new EmptyStackError("Empty stack at dict literal");
}
final int offset = b.getStack().size() - 1;
for (int i = num_args-1; i >= 0; i--) evaluator.push(b.getStack().get(offset - i));
for (int i = 0; i < num_args; i++) b.pop();
}
b.push(this.getDict(b.getContext(), q));
evaluator.dump(_block);

// If we have locals, we will want to pull the data out if it before they are popped
// so we remove the instruction to pop the variables, we will do it ourselves below
if (has_locals) evaluator.getInstructions().getInstrucionList().remove(0);

evaluator.eval();

if (has_locals) {
Dict block_locals = vars.popGet();
dict_scope.update(block_locals);
}

// Pop the dict scope and add it to the stack
b.push(vars.popGet()); // popGet returns dict_scope
}

@Override
public ReprStream repr(ReprStream stream) {
if (num_captures == 0) {
stream.print(":{");
} else {
stream.print("{" + num_captures + ",");
}
BlockUtils.repr(stream, _block, false, null);
stream.print("}");
stream.print(":");
BlockUtils.repr(stream, _block, true, null);
return stream;
}
}
3 changes: 0 additions & 3 deletions src/aya/instruction/EmptyDictLiteralInstruction.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ protected EmptyDictLiteralInstruction() {
super(null, StaticBlock.EMPTY);
}

@Override
public int numCaptures() { return 0; }

public Dict getDict(ExecutionContext context, Queue<Obj> q) {
return new Dict();
}
Expand Down
8 changes: 8 additions & 0 deletions src/aya/obj/block/StaticBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ public boolean hasLocals() {
return _locals != null;
}

public int getNumArgs() {
if (_args == null) {
return 0;
} else {
return _args.size();
}
}

//////////////////////
// Used By BlockOps //
//////////////////////
Expand Down
Loading

0 comments on commit ec73a33

Please sign in to comment.