Function -> Callee & Add callee exception

This commit is contained in:
Astrash
2023-10-27 13:57:53 +11:00
parent ceba9512c7
commit ff031df903
6 changed files with 13 additions and 12 deletions

View File

@@ -156,7 +156,7 @@ tasks.register("genTerrascriptAstClasses") {
ASTNode("Grouping", listOf("expression" to "Expr")), ASTNode("Grouping", listOf("expression" to "Expr")),
ASTNode("Literal", listOf("value" to "Object", "type" to "Type")), ASTNode("Literal", listOf("value" to "Object", "type" to "Type")),
ASTNode("Unary", listOf("operator" to "UnaryOperator", "operand" to "Expr")), ASTNode("Unary", listOf("operator" to "UnaryOperator", "operand" to "Expr")),
ASTNode("Call", listOf("function" to "Expr", "arguments" to "List<Expr>")), ASTNode("Call", listOf("callee" to "Expr", "arguments" to "List<Expr>")),
ASTNode("Variable", listOf("identifier" to "String"), listOf("symbol" to "Symbol", "scope" to "Environment")), ASTNode("Variable", listOf("identifier" to "String"), listOf("symbol" to "Symbol", "scope" to "Environment")),
ASTNode("Assignment", listOf("lValue" to "Variable", "rValue" to "Expr")), ASTNode("Assignment", listOf("lValue" to "Variable", "rValue" to "Expr")),
ASTNode("Void", listOf()), ASTNode("Void", listOf()),
@@ -202,7 +202,7 @@ tasks.register("genTerrascriptAstClasses") {
ASTNode("Grouping", listOf("expression" to "TypedExpr")), ASTNode("Grouping", listOf("expression" to "TypedExpr")),
ASTNode("Literal", listOf("value" to "Object")), ASTNode("Literal", listOf("value" to "Object")),
ASTNode("Unary", listOf("operator" to "UnaryOperator", "operand" to "TypedExpr")), ASTNode("Unary", listOf("operator" to "UnaryOperator", "operand" to "TypedExpr")),
ASTNode("Call", listOf("function" to "TypedExpr", "arguments" to "List<TypedExpr>")), ASTNode("Call", listOf("callee" to "TypedExpr", "arguments" to "List<TypedExpr>")),
ASTNode("Variable", listOf("identifier" to "String")), ASTNode("Variable", listOf("identifier" to "String")),
ASTNode("Assignment", listOf("lValue" to "Variable", "rValue" to "TypedExpr")), ASTNode("Assignment", listOf("lValue" to "Variable", "rValue" to "TypedExpr")),
ASTNode("Void", listOf()), ASTNode("Void", listOf()),

View File

@@ -210,7 +210,7 @@ public class TerraScriptClassGenerator {
@Override @Override
public Void visitCallTypedExpr(Call expr) { public Void visitCallTypedExpr(Call expr) {
// TODO - Remove specific handling of native functions // TODO - Remove specific handling of native functions
if (expr.function.type instanceof Type.Function.Native nativeFunction) { if (expr.callee.type instanceof Type.Function.Native nativeFunction) {
NativeFunction function = nativeFunction.getNativeFunction(); NativeFunction function = nativeFunction.getNativeFunction();
function.pushInstance(method); function.pushInstance(method);
expr.arguments.forEach(a -> a.accept(this)); expr.arguments.forEach(a -> a.accept(this));
@@ -220,7 +220,7 @@ public class TerraScriptClassGenerator {
// TODO - Add support for invokevirtual // TODO - Add support for invokevirtual
expr.arguments.forEach(a -> a.accept(this)); expr.arguments.forEach(a -> a.accept(this));
List<Type> parameters = expr.arguments.stream().map(e -> e.type).toList(); List<Type> parameters = expr.arguments.stream().map(e -> e.type).toList();
method.visitMethodInsn(Opcodes.INVOKESTATIC, className, ((Type.Function) expr.function.type).getId(), getFunctionDescriptor(parameters, expr.type), false); method.visitMethodInsn(Opcodes.INVOKESTATIC, className, ((Type.Function) expr.callee.type).getId(), getFunctionDescriptor(parameters, expr.type), false);
return null; return null;
} }

View File

@@ -1,7 +1,6 @@
package com.dfsek.terra.addons.terrascript.v2.semanticanalysis; package com.dfsek.terra.addons.terrascript.v2.semanticanalysis;
import com.dfsek.terra.addons.terrascript.v2.Environment; import com.dfsek.terra.addons.terrascript.v2.Environment;
import com.dfsek.terra.addons.terrascript.v2.Environment.ScopeException.NonexistentSymbolException;
import com.dfsek.terra.addons.terrascript.v2.Environment.Symbol; import com.dfsek.terra.addons.terrascript.v2.Environment.Symbol;
import com.dfsek.terra.addons.terrascript.v2.ErrorHandler; import com.dfsek.terra.addons.terrascript.v2.ErrorHandler;
import com.dfsek.terra.addons.terrascript.v2.Type; import com.dfsek.terra.addons.terrascript.v2.Type;
@@ -18,7 +17,6 @@ import com.dfsek.terra.addons.terrascript.v2.ast.Expr.Visitor;
import com.dfsek.terra.addons.terrascript.v2.ast.Expr.Void; import com.dfsek.terra.addons.terrascript.v2.ast.Expr.Void;
import com.dfsek.terra.addons.terrascript.v2.ast.Stmt; import com.dfsek.terra.addons.terrascript.v2.ast.Stmt;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.IdentifierAlreadyDeclaredException; import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.IdentifierAlreadyDeclaredException;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.UndefinedReferenceException;
import com.dfsek.terra.api.util.generic.pair.Pair; import com.dfsek.terra.api.util.generic.pair.Pair;
import java.util.List; import java.util.List;
@@ -64,7 +62,7 @@ public class ScopeAnalyzer implements Visitor<Void>, Stmt.Visitor<Void> {
@Override @Override
public Void visitCallExpr(Call expr) { public Void visitCallExpr(Call expr) {
expr.function.accept(this); expr.callee.accept(this);
expr.arguments.forEach(e -> e.accept(this)); expr.arguments.forEach(e -> e.accept(this));
return null; return null;
} }

View File

@@ -3,8 +3,6 @@ package com.dfsek.terra.addons.terrascript.v2.semanticanalysis;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.dfsek.terra.addons.terrascript.v2.Environment;
import com.dfsek.terra.addons.terrascript.v2.Environment.Symbol;
import com.dfsek.terra.addons.terrascript.v2.ErrorHandler; import com.dfsek.terra.addons.terrascript.v2.ErrorHandler;
import com.dfsek.terra.addons.terrascript.v2.Type; import com.dfsek.terra.addons.terrascript.v2.Type;
import com.dfsek.terra.addons.terrascript.v2.ast.Expr.Assignment; import com.dfsek.terra.addons.terrascript.v2.ast.Expr.Assignment;
@@ -19,6 +17,7 @@ import com.dfsek.terra.addons.terrascript.v2.ast.Expr.Void;
import com.dfsek.terra.addons.terrascript.v2.ast.Stmt; import com.dfsek.terra.addons.terrascript.v2.ast.Stmt;
import com.dfsek.terra.addons.terrascript.v2.ast.TypedExpr; import com.dfsek.terra.addons.terrascript.v2.ast.TypedExpr;
import com.dfsek.terra.addons.terrascript.v2.ast.TypedStmt; import com.dfsek.terra.addons.terrascript.v2.ast.TypedStmt;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.InvalidCalleeException;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.InvalidFunctionDeclarationException; import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.InvalidFunctionDeclarationException;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.InvalidTypeException; import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.InvalidTypeException;
import com.dfsek.terra.addons.terrascript.v2.parser.ParseException; import com.dfsek.terra.addons.terrascript.v2.parser.ParseException;
@@ -104,10 +103,10 @@ public class TypeChecker implements Visitor<TypedExpr>, Stmt.Visitor<TypedStmt>
@Override @Override
public TypedExpr visitCallExpr(Call expr) { public TypedExpr visitCallExpr(Call expr) {
TypedExpr function = expr.function.accept(this); TypedExpr function = expr.callee.accept(this);
if(!(function.type instanceof Type.Function functionType)) { if(!(function.type instanceof Type.Function functionType)) {
errorHandler.add(new InvalidTypeException("Cannot call type '" + function.type + "', only functions can be called", expr.position)); errorHandler.add(new InvalidCalleeException("Cannot call type '" + function.type + "', only functions can be called", expr.position));
return new TypedExpr.Void(Type.VOID); return new TypedExpr.Void(Type.VOID);
} }

View File

@@ -62,7 +62,7 @@ public class VariableAnalyzer implements Expr.Visitor<Void>, Stmt.Visitor<Void>
@Override @Override
public Void visitCallExpr(Call expr) { public Void visitCallExpr(Call expr) {
expr.function.accept(this); expr.callee.accept(this);
expr.arguments.forEach(e -> e.accept(this)); expr.arguments.forEach(e -> e.accept(this));
return null; return null;
} }

View File

@@ -2,6 +2,7 @@ package semanticanalysis;
import com.dfsek.terra.addons.terrascript.v2.ErrorHandler; import com.dfsek.terra.addons.terrascript.v2.ErrorHandler;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.IdentifierAlreadyDeclaredException; import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.IdentifierAlreadyDeclaredException;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.InvalidCalleeException;
import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.UndefinedReferenceException; import com.dfsek.terra.addons.terrascript.v2.exception.semanticanalysis.UndefinedReferenceException;
import com.dfsek.terra.addons.terrascript.v2.semanticanalysis.SemanticAnalyzer; import com.dfsek.terra.addons.terrascript.v2.semanticanalysis.SemanticAnalyzer;
import com.dfsek.terra.addons.terrascript.v2.lexer.Lexer; import com.dfsek.terra.addons.terrascript.v2.lexer.Lexer;
@@ -248,6 +249,9 @@ public class SemanticAnalyzerTest {
// Calling function that hasn't been declared // Calling function that hasn't been declared
testInvalid("test();", UndefinedReferenceException.class); testInvalid("test();", UndefinedReferenceException.class);
// Cannot call non functions
testInvalid("var test: num = 1; test();", InvalidCalleeException.class);
// Cannot use functions declared in inner scopes // Cannot use functions declared in inner scopes
testInvalid("{ fun test() {} } test();", UndefinedReferenceException.class); testInvalid("{ fun test() {} } test();", UndefinedReferenceException.class);
testInvalid("test(); { fun test() {} }", UndefinedReferenceException.class); testInvalid("test(); { fun test() {} }", UndefinedReferenceException.class);