org.snapscript.tree.Declaration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of snap-all Show documentation
Show all versions of snap-all Show documentation
Dynamic scripting for the JVM
package org.snapscript.tree;
import java.util.concurrent.atomic.AtomicInteger;
import org.snapscript.core.Evaluation;
import org.snapscript.core.InternalStateException;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.scope.index.Index;
import org.snapscript.core.scope.index.Local;
import org.snapscript.core.scope.index.Table;
import org.snapscript.core.variable.Value;
import org.snapscript.tree.literal.TextLiteral;
public class Declaration {
private final DeclarationAllocator allocator;
private final NameReference reference;
private final AtomicInteger offset;
private final Evaluation value;
public Declaration(TextLiteral identifier) {
this(identifier, null, null);
}
public Declaration(TextLiteral identifier, Constraint constraint) {
this(identifier, constraint, null);
}
public Declaration(TextLiteral identifier, Evaluation value) {
this(identifier, null, value);
}
public Declaration(TextLiteral identifier, Constraint constraint, Evaluation value) {
this.allocator = new DeclarationAllocator(constraint, value);
this.reference = new NameReference(identifier);
this.offset = new AtomicInteger(-1);
this.value = value;
}
public int define(Scope scope, int modifiers) throws Exception {
String name = reference.getName(scope);
if(value != null){
value.define(scope); // must compile value first
}
Index index = scope.getIndex();
int depth = index.index(name);
offset.set(depth);
return depth;
}
public Value compile(Scope scope, int modifiers) throws Exception {
String name = reference.getName(scope);
Local local = allocator.compile(scope, name, modifiers);
Table table = scope.getTable();
int depth = offset.get();
try {
table.add(depth, local);
}catch(Exception e) {
throw new InternalStateException("Declaration of variable '" + name +"' failed", e);
}
return local;
}
public Value declare(Scope scope, int modifiers) throws Exception {
String name = reference.getName(scope);
Local local = allocator.allocate(scope, name, modifiers);
Table table = scope.getTable();
int depth = offset.get();
try {
table.add(depth, local);
}catch(Exception e) {
throw new InternalStateException("Declaration of variable '" + name +"' failed", e);
}
return local;
}
}