mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-28 17:28:03 +00:00
Add TypedLocalVariable and integrate it to Constractur and Methods
This commit is contained in:
parent
938e92f679
commit
827b5551f4
@ -18,7 +18,7 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
|
|||||||
public class TypedAssignment implements TypedStatement {
|
public class TypedAssignment implements TypedStatement {
|
||||||
private String varName;
|
private String varName;
|
||||||
private TypedExpression value;
|
private TypedExpression value;
|
||||||
// private TypedExpression recursiveOwnerChain;
|
// private TypedExpression recursiveOwnerChain;
|
||||||
private Type type;
|
private Type type;
|
||||||
|
|
||||||
public TypedAssignment(Map<String, Type> localVar, TypedClass clas, Assignment untyped) {
|
public TypedAssignment(Map<String, Type> localVar, TypedClass clas, Assignment untyped) {
|
||||||
@ -28,25 +28,30 @@ public class TypedAssignment implements TypedStatement {
|
|||||||
public void convertToTypedAssignment(Map<String, Type> localVar, TypedClass clas, Assignment untyped) {
|
public void convertToTypedAssignment(Map<String, Type> localVar, TypedClass clas, Assignment untyped) {
|
||||||
varName = untyped.location().id();
|
varName = untyped.location().id();
|
||||||
value = convertExpression(localVar, clas, untyped.value());
|
value = convertExpression(localVar, clas, untyped.value());
|
||||||
// recursiveOwnerChain = convertExpression(localVar, clas, untyped.location().recursiveOwnerChain());
|
// recursiveOwnerChain = convertExpression(localVar, clas, untyped.location().recursiveOwnerChain());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||||
Type typeLeft = null;
|
Type typeLeft = null;
|
||||||
|
|
||||||
if (!localVar.containsKey(varName)) {
|
if (clas.isThereField(varName)) {
|
||||||
if (clas.isThereField(varName)) {
|
typeLeft = clas.getFieldType(varName);
|
||||||
typeLeft = clas.getFieldType(varName);
|
|
||||||
} else if (clas.isParameterWitNameInMethod(varName)) {
|
|
||||||
typeLeft = clas.getParameterTypeInCurrentMethod(varName);
|
|
||||||
} else if (clas.isParameterNameInCurrentConstructor(varName)) {
|
|
||||||
typeLeft = clas.getParameterTypeInCurrentConstructor(varName);
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Variable not declared");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
typeLeft = localVar.get(varName);
|
if (clas.isCurrentMethodPresent() && !clas.isCurrentConstructorPresent()) {
|
||||||
|
if (clas.getCurrentMethod().isLocalVariableInMethod(varName)) {
|
||||||
|
typeLeft = clas.getCurrentMethod().getLocalVariableType(varName);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Variable " + varName + " not declared in method");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!clas.isCurrentMethodPresent() && clas.isCurrentConstructorPresent()) {
|
||||||
|
if (clas.getCurrentConstructor().isLocalVariableInConstructor(varName)) {
|
||||||
|
typeLeft = clas.getCurrentConstructor().getLocalVariableType(varName);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Variable " + varName + " not declared in constructor");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type typeRight = value.typeCheck(localVar, clas);
|
Type typeRight = value.typeCheck(localVar, clas);
|
||||||
|
@ -18,7 +18,7 @@ import java.util.Map;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
public class TypedBlock implements TypedNode {
|
public class TypedBlock implements TypedNode {
|
||||||
private List<TypedDeclaration> vars = new ArrayList<>();
|
private List<TypedLocalVariable> vars = new ArrayList<>();
|
||||||
private List<TypedStatement> stmts = new ArrayList<>();
|
private List<TypedStatement> stmts = new ArrayList<>();
|
||||||
private Type type;
|
private Type type;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ public class TypedBlock implements TypedNode {
|
|||||||
convertToTypedBlock(localVar, clas, unTypedBlock);
|
convertToTypedBlock(localVar, clas, unTypedBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedBlock(List<TypedDeclaration> vars, List<TypedStatement> stmts) {
|
public TypedBlock(List<TypedLocalVariable> vars, List<TypedStatement> stmts) {
|
||||||
this.vars = vars;
|
this.vars = vars;
|
||||||
this.stmts = stmts;
|
this.stmts = stmts;
|
||||||
}
|
}
|
||||||
@ -37,11 +37,10 @@ public class TypedBlock implements TypedNode {
|
|||||||
if (unTypedBlock == null) {
|
if (unTypedBlock == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
for (Declaration var : unTypedBlock.localVariables()) {
|
for (Declaration var : unTypedBlock.localVariables()) {
|
||||||
TypedDeclaration typedVar = new TypedDeclaration(localVar, clas, var);
|
vars.add(new TypedLocalVariable(localVar, clas, var));
|
||||||
vars.add(typedVar);
|
}
|
||||||
} */
|
|
||||||
|
|
||||||
for (var stmt : unTypedBlock.stmts()) {
|
for (var stmt : unTypedBlock.stmts()) {
|
||||||
if (stmt instanceof Assignment assignment) {
|
if (stmt instanceof Assignment assignment) {
|
||||||
@ -105,10 +104,6 @@ public class TypedBlock implements TypedNode {
|
|||||||
@Override
|
@Override
|
||||||
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||||
|
|
||||||
for (TypedDeclaration var : vars) {
|
|
||||||
var.typeCheck(localVar, clas);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TypedStatement stmt : stmts) {
|
for (TypedStatement stmt : stmts) {
|
||||||
stmt.typeCheck(localVar, clas);
|
stmt.typeCheck(localVar, clas);
|
||||||
}
|
}
|
||||||
@ -119,7 +114,7 @@ public class TypedBlock implements TypedNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void codeGen(MethodVisitor mv, MethodContext ctx) {
|
public void codeGen(MethodVisitor mv, MethodContext ctx) {
|
||||||
for (TypedDeclaration var : vars) {
|
for (TypedLocalVariable var : vars) {
|
||||||
//var.codeGen(mv, ctx);
|
//var.codeGen(mv, ctx);
|
||||||
}
|
}
|
||||||
for (TypedStatement stmt : stmts) {
|
for (TypedStatement stmt : stmts) {
|
||||||
|
@ -26,6 +26,7 @@ public class TypedConstructor implements TypedNode {
|
|||||||
private List<TypedParameter> typedParameters = new ArrayList<>();
|
private List<TypedParameter> typedParameters = new ArrayList<>();
|
||||||
private TypedBlock typedBlock;
|
private TypedBlock typedBlock;
|
||||||
private Type type;
|
private Type type;
|
||||||
|
private List<TypedLocalVariable> localVariables = new ArrayList<>();
|
||||||
|
|
||||||
public TypedConstructor(String name, List<TypedParameter> typedParameters, TypedBlock typedBlock) {
|
public TypedConstructor(String name, List<TypedParameter> typedParameters, TypedBlock typedBlock) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -37,6 +38,21 @@ public class TypedConstructor implements TypedNode {
|
|||||||
convertToTypedConstructor(localVar, clas, unTypedConstructor);
|
convertToTypedConstructor(localVar, clas, unTypedConstructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isLocalVariablePresent(String localVarName) {
|
||||||
|
return localVariables.stream().anyMatch(localVariable -> localVariable.getName().equals(localVarName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParameterPresent(String parameterName) {
|
||||||
|
return typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocalVariableInConstructor(String localVarName) {
|
||||||
|
return isLocalVariablePresent(localVarName) || isParameterPresent(localVarName);
|
||||||
|
}
|
||||||
|
public Type getLocalVariableType(String localVarName) {
|
||||||
|
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
|
||||||
|
}
|
||||||
|
|
||||||
public void convertToTypedConstructor(Map<String, Type> localVar, TypedClass clas, Constructor unTypedConstructor) {
|
public void convertToTypedConstructor(Map<String, Type> localVar, TypedClass clas, Constructor unTypedConstructor) {
|
||||||
name = unTypedConstructor.className();
|
name = unTypedConstructor.className();
|
||||||
|
|
||||||
|
@ -23,16 +23,16 @@ public final class TypedDeclaration implements TypedNode {
|
|||||||
private Type type;
|
private Type type;
|
||||||
|
|
||||||
public TypedDeclaration(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
public TypedDeclaration(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||||
convertToTypedLocalVariable(localVar, clas, declaration);
|
convertToTypedDeclaration(localVar, clas, declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void convertToTypedLocalVariable(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
public void convertToTypedDeclaration(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||||
if (localVar.containsKey(declaration.name())) {
|
if (localVar.containsKey(declaration.name())) {
|
||||||
throw new RuntimeException("Variable " + declaration.name() + " already declared");
|
throw new RuntimeException("Variable " + declaration.name() + " already declared");
|
||||||
}
|
}
|
||||||
name = declaration.name();
|
name = declaration.name();
|
||||||
type = declaration.type();
|
type = declaration.type();
|
||||||
//localVar.put(this.name, this.type);
|
typeCheck(localVar, clas);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
package de.maishai.typedast.typedclass;
|
||||||
|
|
||||||
|
import de.maishai.ast.records.Declaration;
|
||||||
|
import de.maishai.typedast.MethodContext;
|
||||||
|
import de.maishai.typedast.TypedNode;
|
||||||
|
import de.maishai.typedast.Type;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static de.maishai.typedast.Type.Kind.REFERENCE;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public final class TypedLocalVariable implements TypedNode {
|
||||||
|
private String name;
|
||||||
|
private Type type;
|
||||||
|
|
||||||
|
public TypedLocalVariable(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||||
|
convertToTypedLocalVariable(localVar, clas, declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void convertToTypedLocalVariable(Map<String, Type> localVar, TypedClass clas, Declaration declaration) {
|
||||||
|
if (localVar.containsKey(declaration.name())) {
|
||||||
|
throw new RuntimeException("Variable " + declaration.name() + " already declared");
|
||||||
|
}
|
||||||
|
name = declaration.name();
|
||||||
|
type = declaration.type();
|
||||||
|
typeCheck(localVar, clas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type typeCheck(Map<String, Type> localVar, TypedClass clas) {
|
||||||
|
if (clas.isCurrentMethodPresent() && !clas.isCurrentConstructorPresent()){
|
||||||
|
if(clas.getCurrentMethod().isLocalVariableInMethod(name)){
|
||||||
|
throw new RuntimeException("Variable " + name + " already declared");
|
||||||
|
}
|
||||||
|
clas.getCurrentMethod().getLocalVariables().add(this);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
if (!clas.isCurrentMethodPresent() && clas.isCurrentConstructorPresent()){
|
||||||
|
if(clas.getCurrentConstructor().isLocalVariableInConstructor(name)){
|
||||||
|
throw new RuntimeException("Variable " + name + " already declared");
|
||||||
|
}
|
||||||
|
clas.getCurrentConstructor().getLocalVariables().add(this);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("not found method or constructor in class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void codeGen(ClassWriter cw) {
|
||||||
|
int access = Opcodes.ACC_PUBLIC; // laut Andi ist es ok, dass alle Felder public sind
|
||||||
|
cw.visitField(access, name, type.getDescriptor(), null, null).visitEnd();
|
||||||
|
}
|
||||||
|
}
|
@ -21,21 +21,12 @@ public class TypedMethod implements TypedNode {
|
|||||||
private Type returnType;
|
private Type returnType;
|
||||||
private List<TypedParameter> typedParameters = new ArrayList<>();
|
private List<TypedParameter> typedParameters = new ArrayList<>();
|
||||||
private TypedBlock typedBlock;
|
private TypedBlock typedBlock;
|
||||||
//private List<TypedLocalVariable> localVariables = new ArrayList<>();
|
private List<TypedLocalVariable> localVariables = new ArrayList<>();
|
||||||
|
|
||||||
public TypedMethod(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
public TypedMethod(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
||||||
convertToTypedMethod(localVar, clas, unTypedMethod);
|
convertToTypedMethod(localVar, clas, unTypedMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj instanceof TypedMethod) {
|
|
||||||
TypedMethod other = (TypedMethod) obj;
|
|
||||||
return name.equals(other.name) && returnType.equals(other.returnType) && typedParameters.equals(other.typedParameters);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void convertToTypedMethod(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
public void convertToTypedMethod(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
||||||
|
|
||||||
name = unTypedMethod.methodName();
|
name = unTypedMethod.methodName();
|
||||||
@ -56,6 +47,19 @@ public class TypedMethod implements TypedNode {
|
|||||||
public void convertToTypedBlock(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
public void convertToTypedBlock(Map<String, Type> localVar, TypedClass clas, Method unTypedMethod) {
|
||||||
typedBlock = new TypedBlock(localVar, clas, unTypedMethod.block());
|
typedBlock = new TypedBlock(localVar, clas, unTypedMethod.block());
|
||||||
}
|
}
|
||||||
|
public boolean isLocalVariablePresent(String localVarName) {
|
||||||
|
return localVariables.stream().anyMatch(localVariable -> localVariable.getName().equals(localVarName));
|
||||||
|
}
|
||||||
|
public boolean isParameterPresent(String parameterName) {
|
||||||
|
return typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocalVariableInMethod(String localVarName) {
|
||||||
|
return isLocalVariablePresent(localVarName) || isParameterPresent(localVarName);
|
||||||
|
}
|
||||||
|
public Type getLocalVariableType(String localVarName) {
|
||||||
|
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,6 +74,15 @@ public class TypedMethod implements TypedNode {
|
|||||||
return returnType;
|
return returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof TypedMethod) {
|
||||||
|
TypedMethod other = (TypedMethod) obj;
|
||||||
|
return name.equals(other.name) && returnType.equals(other.returnType) && typedParameters.equals(other.typedParameters);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void codeGen(ClassWriter cw) {
|
public void codeGen(ClassWriter cw) {
|
||||||
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
|
int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok
|
||||||
|
Loading…
Reference in New Issue
Block a user