Untitled
unknown
plain_text
6 days ago
3.1 kB
7
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