Untitled
unknown
plain_text
6 months ago
3.1 kB
9
Indexable
@Override
public Ir.Expr.ObjectExpr visit(Ast.Expr.ObjectExpr ast) throws AnalyzeException {
if (ast.name().isPresent()){
if (Environment.TYPES.containsKey(ast.name().get())){
throw new AnalyzeException("Object " + ast.name().get() + " is already defined");
}
}
Scope objScope = new Scope(null);
List<Ir.Stmt.Let> fields = new ArrayList<>();
for (var field : ast.fields()){
Optional<Type> type = Optional.empty();
if (field.type().isPresent()) {
type = Optional.of(Environment.TYPES.get(field.type()));
}
Optional<Ir.Expr> value = field.value().isPresent()
? Optional.of(visit(field.value().get()))
: Optional.empty();
var variableType = type.or(() -> value.map(expr -> expr.type())).orElse(Type.ANY);
if (value.isPresent()) {
requireSubtype(value.get().type(), variableType);
}
objScope.define(field.name(), variableType);
fields.add(new Ir.Stmt.Let(field.name(), variableType, value));
}
List<Ir.Stmt.Def> methods = new ArrayList<>();
for (var method : ast.methods()){
if (scope.get(method.name(), true).isPresent()){
throw new AnalyzeException("Method " + ast.name() + " has already been defined in the current scope");
}
List<Type> types = new ArrayList<>();
for (var param : method.parameterTypes()) {
if (scope.get(param.get(), true).isPresent()){
throw new AnalyzeException("Function " + ast.name() + " has already been defined in the current scope");
}
Type type = Environment.TYPES.get(param.get());
types.add(type);
}
Type returnType = Type.ANY;
if (method.returnType().isPresent()){
returnType = Environment.TYPES.get(method.returnType().get());
}
objScope.define(method.name(), new Type.Function(types, returnType));
int index = 0;
var testScope = new Scope(objScope);
List<Ir.Stmt.Def.Parameter> params = new ArrayList<>();
for (var param : method.parameters()) {
testScope.define(param, types.get(index));
params.add(new Ir.Stmt.Def.Parameter(param, types.get(index)));
index++;
}
testScope.define("$RETURNS", returnType);
List<Ir.Stmt> body = new ArrayList<>();
for (var stmts : method.body()){
var currentStmt = visit(stmts);
body.add(currentStmt);
}
methods.add(new Ir.Stmt.Def(method.name(), params, returnType, body));
}
Type obj = new Type.Object(objScope);
return new Ir.Expr.ObjectExpr(ast.name(), fields, methods, obj);
}Editor is loading...
Leave a Comment