package com.pixelmaid.dresscode.antlr.types.tree; import com.pixelmaid.dresscode.antlr.types.Scope; import com.pixelmaid.dresscode.antlr.types.VarType; import com.pixelmaid.dresscode.drawing.primitive2d.Drawable; import com.pixelmaid.dresscode.events.CustomEvent; import java.util.ArrayList; import java.util.List; public class AssignmentNode extends NodeEvent implements DCNode { protected String identifier; protected List<DCNode> indexNodes; protected DCNode rhs; protected Scope scope; protected int line; public AssignmentNode(String i, List<DCNode> e, DCNode n, Scope s, int l) { identifier = i; indexNodes = (e == null) ? new ArrayList<DCNode>() : e; rhs = (n == null) ? null : n; scope = s; line = l; } @Override public VarType evaluate() { VarType value; if(rhs!=null){ value = rhs.evaluate(); } else{ value=new VarType(null); } value.setLine(line); /* if (value == VarType.VOID) { throw new RuntimeException("can't assign VOID to " + identifier); }*/ if (indexNodes.isEmpty()) { // a simple assignment scope.assign(identifier, value); if(value.isDrawable()){ Drawable d = value.asDrawable(); d.setIdentifier(identifier); } } else { // a possible list-lookup and reassignment VarType list = scope.resolve(identifier); // iterate up to `foo[x][y]` in case of `foo[x][y][z] = 42;` for (int i = 0; i < indexNodes.size() - 1 && list != null; i++) { VarType index = indexNodes.get(i).evaluate(); if (!index.isNumber() || !list.isList()) { // sanity checks throw new RuntimeException("illegal statement: " + this); } int idx = index.asLong().intValue(); list = list.asList().get(idx); } // list is now pointing to `foo[x][y]` in case of `foo[x][y][z] = 42;` // get the value `z`: the last index, in `foo[x][y][z] = 42;` VarType lastIndex = indexNodes.get(indexNodes.size() - 1).evaluate(); if (!lastIndex.isNumber() || !list.isList()) { // sanity checks throw new RuntimeException("illegal statement: " + this); } // re-assign `foo[x][y][z]` List<VarType> existing = list.asList(); existing.set(lastIndex.asLong().intValue(), value); } return VarType.VOID; } @Override public String toString() { return String.format("(%s[%s] = %s)", identifier, indexNodes, rhs); } }