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("Literal", listOf("value" to "Object", "type" to "Type")),
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("Assignment", listOf("lValue" to "Variable", "rValue" to "Expr")),
ASTNode("Void", listOf()),
@@ -202,7 +202,7 @@ tasks.register("genTerrascriptAstClasses") {
ASTNode("Grouping", listOf("expression" to "TypedExpr")),
ASTNode("Literal", listOf("value" to "Object")),
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("Assignment", listOf("lValue" to "Variable", "rValue" to "TypedExpr")),
ASTNode("Void", listOf()),

View File

@@ -210,7 +210,7 @@ public class TerraScriptClassGenerator {
@Override
public Void visitCallTypedExpr(Call expr) {
// 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();
function.pushInstance(method);
expr.arguments.forEach(a -> a.accept(this));
@@ -220,7 +220,7 @@ public class TerraScriptClassGenerator {
// TODO - Add support for invokevirtual
expr.arguments.forEach(a -> a.accept(this));
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;
}

View File

@@ -1,7 +1,6 @@
package com.dfsek.terra.addons.terrascript.v2.semanticanalysis;
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.ErrorHandler;
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.Stmt;
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 java.util.List;
@@ -64,7 +62,7 @@ public class ScopeAnalyzer implements Visitor<Void>, Stmt.Visitor<Void> {
@Override
public Void visitCallExpr(Call expr) {
expr.function.accept(this);
expr.callee.accept(this);
expr.arguments.forEach(e -> e.accept(this));
return null;
}

View File

@@ -3,8 +3,6 @@ package com.dfsek.terra.addons.terrascript.v2.semanticanalysis;
import java.util.List;
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.Type;
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.TypedExpr;
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.InvalidTypeException;
import com.dfsek.terra.addons.terrascript.v2.parser.ParseException;
@@ -104,10 +103,10 @@ public class TypeChecker implements Visitor<TypedExpr>, Stmt.Visitor<TypedStmt>
@Override
public TypedExpr visitCallExpr(Call expr) {
TypedExpr function = expr.function.accept(this);
TypedExpr function = expr.callee.accept(this);
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);
}

View File

@@ -62,7 +62,7 @@ public class VariableAnalyzer implements Expr.Visitor<Void>, Stmt.Visitor<Void>
@Override
public Void visitCallExpr(Call expr) {
expr.function.accept(this);
expr.callee.accept(this);
expr.arguments.forEach(e -> e.accept(this));
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.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.semanticanalysis.SemanticAnalyzer;
import com.dfsek.terra.addons.terrascript.v2.lexer.Lexer;
@@ -248,6 +249,9 @@ public class SemanticAnalyzerTest {
// Calling function that hasn't been declared
testInvalid("test();", UndefinedReferenceException.class);
// Cannot call non functions
testInvalid("var test: num = 1; test();", InvalidCalleeException.class);
// Cannot use functions declared in inner scopes
testInvalid("{ fun test() {} } test();", UndefinedReferenceException.class);
testInvalid("test(); { fun test() {} }", UndefinedReferenceException.class);