Merge branch 'refs/heads/main' into codeGen

# Conflicts:
#	src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java
#	src/main/java/de/maishai/typedast/typedclass/TypedBinary.java
#	src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java
#	src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java
#	src/main/java/de/maishai/typedast/typedclass/TypedNew.java
#	src/main/java/de/maishai/typedast/typedclass/TypedUnary.java
#	src/main/resources/JavaTestfiles/ClassCanBeTyped.java
This commit is contained in:
404Simon 2024-05-15 20:22:18 +02:00
commit f1b366e157
60 changed files with 2234 additions and 857 deletions

Binary file not shown.

View File

@ -38,6 +38,7 @@ expr : expr binaryOp expr #BinaryOperation
| '(' expr ')' #Expression | '(' expr ')' #Expression
| fieldVarAccess #Identifier | fieldVarAccess #Identifier
| stmtexpr #StatementExpressionexpr | stmtexpr #StatementExpressionexpr
| THIS #This
| NULL #Null | NULL #Null
; ;

View File

@ -3,47 +3,37 @@ package de.maishai;
import de.maishai.antlr.DecafLexer; import de.maishai.antlr.DecafLexer;
import de.maishai.antlr.DecafParser; import de.maishai.antlr.DecafParser;
import de.maishai.ast.records.Class; import de.maishai.ast.records.Class;
import de.maishai.ast.records.Program;
import de.maishai.typedast.CodeGenUtils; import de.maishai.typedast.CodeGenUtils;
import de.maishai.typedast.typedclass.TypedClass; import de.maishai.typedast.typedclass.TypedClass;
import de.maishai.typedast.typedclass.TypedProgram;
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.*;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/** /**
* Decaf language Compiler * Decaf language Compiler
*/ */
public class Compiler { public class Compiler {
/*
public static void main(String[] args) {
generateAST("""
public class ClassWithConstructorWithParameters {
int x;
public ClassWithConstructorWithParameters(int startValue, int repetitions) {
this.x = startValue;
while (repetitions > 0) {
int innerRepetitions;
innerRepetitions = this.x;
while (innerRepetitions > 0) {
this.x = this.x * this.x;
innerRepetitions -= 1;
}
repetitions -= 1;
}
}
}
""");
} */
public static Class generateAST(String fromSource) { public static Program generateAST(List<String> fromSources) {
List<Class> classes = new ArrayList<>();
for (String fromSource : fromSources) {
CharStream input = CharStreams.fromString(fromSource); CharStream input = CharStreams.fromString(fromSource);
DecafLexer lexer = new DecafLexer(input); DecafLexer lexer = new DecafLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer); CommonTokenStream tokens = new CommonTokenStream(lexer);
DecafParser parser = new DecafParser(tokens); DecafParser parser = new DecafParser(tokens);
DecafParser.ClassContext tree = parser.class_(); //Parsen DecafParser.ClassContext tree = parser.class_(); //Parsen
return ASTGenerator.generateAST(tree); classes.add(ASTGenerator.generateAST(tree));
}
return new Program(classes);
} }
public static Class generateASTFromFile(String sourcePath) { public static Program generateASTFromFile(List<String> sourcePaths) {
List<String> sources = new ArrayList<>();
for (String sourcePath : sourcePaths) {
ANTLRInputStream antlrInputStream; ANTLRInputStream antlrInputStream;
try { try {
antlrInputStream = new ANTLRFileStream(sourcePath); antlrInputStream = new ANTLRFileStream(sourcePath);
@ -51,26 +41,32 @@ public class Compiler {
System.out.println("Ungültiger Dateipfad D:"); System.out.println("Ungültiger Dateipfad D:");
throw new RuntimeException("Ungültiger Dateipfad D:"); throw new RuntimeException("Ungültiger Dateipfad D:");
} }
return generateAST(antlrInputStream.toString()); sources.add(antlrInputStream.toString());
}
return generateAST(sources);
} }
public static TypedClass generateTypedASTFromAst(Class ast) { public static TypedProgram generateTypedASTFromAst(Program ast) {
TypedClass typedAST = new TypedClass(); return new TypedProgram(ast);
typedAST = (TypedClass) typedAST.startConversion(ast);
return typedAST;
} }
public static byte[] generateByteCodeArrayFromTypedAst(TypedClass typedAST) { public static byte[] generateByteCodeArrayFromTypedAst(TypedClass typedAST) {
return typedAST.codeGen(); return typedAST.codeGen();
} }
public static byte[] generateByteCodeArray(String fromSource) { public static List<byte[]> generateByteCodeArray(List<String> fromSources) {
Class ast = generateAST(fromSource); Program ast = generateAST(fromSources);
TypedClass typedAST = generateTypedASTFromAst(ast); TypedProgram typedAST = generateTypedASTFromAst(ast);
return generateByteCodeArrayFromTypedAst(typedAST); List<byte[]> byteCode = new ArrayList<>();
for (TypedClass c : typedAST.getTypedClasses()) {
byteCode.add(generateByteCodeArrayFromTypedAst(c));
}
return byteCode;
} }
public static byte[] generateByteCodeArrayFromFile(String sourcePath) { public static List<byte[]> generateByteCodeArrayFromFile(List<String> sourcePaths) {
List<Class> classes = new ArrayList<>();
for (String sourcePath : sourcePaths) {
ANTLRInputStream antlrInputStream; ANTLRInputStream antlrInputStream;
try { try {
antlrInputStream = new ANTLRFileStream(sourcePath); antlrInputStream = new ANTLRFileStream(sourcePath);
@ -83,16 +79,28 @@ public class Compiler {
DecafParser parser = new DecafParser(tokens); DecafParser parser = new DecafParser(tokens);
DecafParser.ClassContext tree = parser.class_(); //Parsen DecafParser.ClassContext tree = parser.class_(); //Parsen
Class ast = ASTGenerator.generateAST(tree); Class ast = ASTGenerator.generateAST(tree);
TypedClass typedAST = generateTypedASTFromAst(ast); classes.add(ast);
return generateByteCodeArrayFromTypedAst(typedAST); }
Program program = new Program(classes);
TypedProgram typedAST = generateTypedASTFromAst(program);
List<byte[]> byteCode = new ArrayList<>();
for (TypedClass c : typedAST.getTypedClasses()) {
byteCode.add(generateByteCodeArrayFromTypedAst(c));
}
return byteCode;
} }
public static void generateByteCodeFileFromFile(String sourcePath, String classname) { public static void generateByteCodeFileFromFile(List<String> sourcePath, List<String> classname) {
byte[] bytes = generateByteCodeArrayFromFile(sourcePath); List<byte[]> bytes = generateByteCodeArrayFromFile(sourcePath);
CodeGenUtils.writeClassfile(bytes, classname); for (int i = 0; i < bytes.size(); i++) {
CodeGenUtils.writeClassfile(bytes.get(i), classname.get(i));
}
} }
public static void main(String[] args) { public static void main(String[] args) {
generateByteCodeFileFromFile("src/main/resources/JavaTestfiles/ClassCanBeTyped.java", "ClassCanBeTyped"); generateByteCodeFileFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructor.java",
"src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java",
"src/main/resources/JavaTestfiles/ComplexClass.java"),
List.of("ClassWithConstructor","ClassWithConstructorAndMethodCall","ComplexClass"));
} }
} }

View File

@ -53,12 +53,18 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
} }
public static Expression generateConstant(DecafParser.LiteralContext ctx) { public static Expression generateConstant(DecafParser.LiteralContext ctx) {
if (ctx.NUMBER() != null) if (ctx.NUMBER() != null) {
return new IntLiteral(Integer.valueOf(ctx.NUMBER().getText())); return new IntLiteral(Integer.valueOf(ctx.NUMBER().getText()));
if (ctx.BOOLEANLITERAL() != null) }
if (ctx.BOOLEANLITERAL() != null) {
return new BoolLiteral(Boolean.valueOf(ctx.BOOLEANLITERAL().getText())); return new BoolLiteral(Boolean.valueOf(ctx.BOOLEANLITERAL().getText()));
if (ctx.CHARLITERAL() != null) }
return new CharLiteral(ctx.CHARLITERAL().getText().charAt(0)); if (ctx.CHARLITERAL() != null) {
if (ctx.CHARLITERAL().getText().length() != 3) {
throw new RuntimeException("Wrong format for Char literal. Good format: 'c' Bad format: " + ctx.CHARLITERAL().getText());
}
return new CharLiteral(ctx.CHARLITERAL().getText().charAt(1));
}
throw new RuntimeException("No literal found!"); throw new RuntimeException("No literal found!");
} }
@ -93,7 +99,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
recursiveOwnerChain = generateRecursiveOwnerChain(recipientList, null); recursiveOwnerChain = generateRecursiveOwnerChain(recipientList, null);
} }
List<Expression> args = new ArrayList<>(); List<Expression> args = new ArrayList<>();
if(ctx.methCall().methName().args() != null){ if (ctx.methCall().methName().args() != null) {
for (var expr : ctx.methCall().methName().args().expr()) { for (var expr : ctx.methCall().methName().args().expr()) {
Expression astExpr = expr.accept(this); Expression astExpr = expr.accept(this);
args.add(astExpr); args.add(astExpr);
@ -115,6 +121,16 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
return new New(type, args); return new New(type, args);
} }
@Override
public Expression visitNull(DecafParser.NullContext ctx){
return new Null();
}
@Override
public Expression visitThis(DecafParser.ThisContext ctx){
return new This();
}
public static Expression generateRecursiveOwnerChain(List<DecafParser.RecipientContext> ctxList, FieldVarAccess recipient) { public static Expression generateRecursiveOwnerChain(List<DecafParser.RecipientContext> ctxList, FieldVarAccess recipient) {
if (ctxList.isEmpty()) { if (ctxList.isEmpty()) {
return recipient; return recipient;
@ -123,7 +139,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
DecafParser.RecipientContext ctx = ctxList.get(lastElement); DecafParser.RecipientContext ctx = ctxList.get(lastElement);
ctxList.remove(lastElement); ctxList.remove(lastElement);
if (ctx.id() != null) { if (ctx.id() != null) {
return new FieldVarAccess(false, generateRecursiveOwnerChain(ctxList, recipient), ctx.id().IDENTIFIER().getText()); return new FieldVarAccess(true, generateRecursiveOwnerChain(ctxList, recipient), ctx.id().IDENTIFIER().getText());
} }
if (ctx.methName() != null) { if (ctx.methName() != null) {
List<Expression> args = new ArrayList<>(); List<Expression> args = new ArrayList<>();

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
// Generated from C:/dev/Pressmium/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1 // Generated from C:/Users/laure/Documents/Dev/Compilerbau/Projekt/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1
package de.maishai.antlr; package de.maishai.antlr;
import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.ParserRuleContext;
@ -360,6 +360,18 @@ public class DecafBaseListener implements DecafListener {
* <p>The default implementation does nothing.</p> * <p>The default implementation does nothing.</p>
*/ */
@Override public void exitBinaryOperation(DecafParser.BinaryOperationContext ctx) { } @Override public void exitBinaryOperation(DecafParser.BinaryOperationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterThis(DecafParser.ThisContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitThis(DecafParser.ThisContext ctx) { }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

View File

@ -1,4 +1,4 @@
// Generated from C:/dev/Pressmium/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1 // Generated from C:/Users/laure/Documents/Dev/Compilerbau/Projekt/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1
package de.maishai.antlr; package de.maishai.antlr;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
@ -215,6 +215,13 @@ public class DecafBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p> * {@link #visitChildren} on {@code ctx}.</p>
*/ */
@Override public T visitBinaryOperation(DecafParser.BinaryOperationContext ctx) { return visitChildren(ctx); } @Override public T visitBinaryOperation(DecafParser.BinaryOperationContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitThis(DecafParser.ThisContext ctx) { return visitChildren(ctx); }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

View File

@ -1,4 +1,4 @@
// Generated from C:/dev/Pressmium/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1 // Generated from C:/Users/laure/Documents/Dev/Compilerbau/Projekt/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1
package de.maishai.antlr; package de.maishai.antlr;
import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStream;

View File

@ -1,4 +1,4 @@
// Generated from C:/dev/Pressmium/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1 // Generated from C:/Users/laure/Documents/Dev/Compilerbau/Projekt/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1
package de.maishai.antlr; package de.maishai.antlr;
import org.antlr.v4.runtime.tree.ParseTreeListener; import org.antlr.v4.runtime.tree.ParseTreeListener;
@ -331,6 +331,18 @@ public interface DecafListener extends ParseTreeListener {
* @param ctx the parse tree * @param ctx the parse tree
*/ */
void exitBinaryOperation(DecafParser.BinaryOperationContext ctx); void exitBinaryOperation(DecafParser.BinaryOperationContext ctx);
/**
* Enter a parse tree produced by the {@code This}
* labeled alternative in {@link DecafParser#expr}.
* @param ctx the parse tree
*/
void enterThis(DecafParser.ThisContext ctx);
/**
* Exit a parse tree produced by the {@code This}
* labeled alternative in {@link DecafParser#expr}.
* @param ctx the parse tree
*/
void exitThis(DecafParser.ThisContext ctx);
/** /**
* Enter a parse tree produced by the {@code StatementExpressionexpr} * Enter a parse tree produced by the {@code StatementExpressionexpr}
* labeled alternative in {@link DecafParser#expr}. * labeled alternative in {@link DecafParser#expr}.

View File

@ -1,4 +1,4 @@
// Generated from C:/dev/Pressmium/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1 // Generated from C:/Users/laure/Documents/Dev/Compilerbau/Projekt/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1
package de.maishai.antlr; package de.maishai.antlr;
import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA; import org.antlr.v4.runtime.dfa.DFA;
@ -1580,6 +1580,24 @@ public class DecafParser extends Parser {
} }
} }
@SuppressWarnings("CheckReturnValue") @SuppressWarnings("CheckReturnValue")
public static class ThisContext extends ExprContext {
public TerminalNode THIS() { return getToken(DecafParser.THIS, 0); }
public ThisContext(ExprContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof DecafListener ) ((DecafListener)listener).enterThis(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof DecafListener ) ((DecafListener)listener).exitThis(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof DecafVisitor ) return ((DecafVisitor<? extends T>)visitor).visitThis(this);
else return visitor.visitChildren(this);
}
}
@SuppressWarnings("CheckReturnValue")
public static class StatementExpressionexprContext extends ExprContext { public static class StatementExpressionexprContext extends ExprContext {
public StmtexprContext stmtexpr() { public StmtexprContext stmtexpr() {
return getRuleContext(StmtexprContext.class,0); return getRuleContext(StmtexprContext.class,0);
@ -1615,7 +1633,7 @@ public class DecafParser extends Parser {
int _alt; int _alt;
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(212); setState(213);
_errHandler.sync(this); _errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) {
case 1: case 1:
@ -1627,7 +1645,7 @@ public class DecafParser extends Parser {
setState(201); setState(201);
unaryOp(); unaryOp();
setState(202); setState(202);
expr(6); expr(7);
} }
break; break;
case 2: case 2:
@ -1672,16 +1690,25 @@ public class DecafParser extends Parser {
break; break;
case 6: case 6:
{ {
_localctx = new NullContext(_localctx); _localctx = new ThisContext(_localctx);
_ctx = _localctx; _ctx = _localctx;
_prevctx = _localctx; _prevctx = _localctx;
setState(211); setState(211);
match(THIS);
}
break;
case 7:
{
_localctx = new NullContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(212);
match(NULL); match(NULL);
} }
break; break;
} }
_ctx.stop = _input.LT(-1); _ctx.stop = _input.LT(-1);
setState(220); setState(221);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,17,_ctx); _alt = getInterpreter().adaptivePredict(_input,17,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@ -1692,16 +1719,16 @@ public class DecafParser extends Parser {
{ {
_localctx = new BinaryOperationContext(new ExprContext(_parentctx, _parentState)); _localctx = new BinaryOperationContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr); pushNewRecursionContext(_localctx, _startState, RULE_expr);
setState(214);
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
setState(215); setState(215);
binaryOp(); if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
setState(216); setState(216);
expr(8); binaryOp();
setState(217);
expr(9);
} }
} }
} }
setState(222); setState(223);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,17,_ctx); _alt = getInterpreter().adaptivePredict(_input,17,_ctx);
} }
@ -1757,7 +1784,7 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(223); setState(224);
_la = _input.LA(1); _la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 17171480576L) != 0)) ) { if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 17171480576L) != 0)) ) {
_errHandler.recoverInline(this); _errHandler.recoverInline(this);
@ -1810,7 +1837,7 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(225); setState(226);
_la = _input.LA(1); _la = _input.LA(1);
if ( !(_la==SUB || _la==NOT) ) { if ( !(_la==SUB || _la==NOT) ) {
_errHandler.recoverInline(this); _errHandler.recoverInline(this);
@ -1872,37 +1899,37 @@ public class DecafParser extends Parser {
int _alt; int _alt;
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(229); setState(230);
_errHandler.sync(this); _errHandler.sync(this);
_la = _input.LA(1); _la = _input.LA(1);
if (_la==THIS) { if (_la==THIS) {
{ {
setState(227);
match(THIS);
setState(228); setState(228);
match(THIS);
setState(229);
match(T__17); match(T__17);
} }
} }
setState(236); setState(237);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,19,_ctx); _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) { if ( _alt==1 ) {
{ {
{ {
setState(231);
recipient();
setState(232); setState(232);
recipient();
setState(233);
match(T__17); match(T__17);
} }
} }
} }
setState(238); setState(239);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,19,_ctx); _alt = getInterpreter().adaptivePredict(_input,19,_ctx);
} }
setState(239); setState(240);
id(); id();
} }
} }
@ -1953,11 +1980,11 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(241);
fieldVarAccess();
setState(242); setState(242);
assignSign(); fieldVarAccess();
setState(243); setState(243);
assignSign();
setState(244);
expr(0); expr(0);
} }
} }
@ -2011,37 +2038,37 @@ public class DecafParser extends Parser {
int _alt; int _alt;
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(247); setState(248);
_errHandler.sync(this); _errHandler.sync(this);
_la = _input.LA(1); _la = _input.LA(1);
if (_la==THIS) { if (_la==THIS) {
{ {
setState(245);
match(THIS);
setState(246); setState(246);
match(THIS);
setState(247);
match(T__17); match(T__17);
} }
} }
setState(254); setState(255);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,21,_ctx); _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) { if ( _alt==1 ) {
{ {
{ {
setState(249);
recipient();
setState(250); setState(250);
recipient();
setState(251);
match(T__17); match(T__17);
} }
} }
} }
setState(256); setState(257);
_errHandler.sync(this); _errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,21,_ctx); _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
} }
setState(257); setState(258);
methName(); methName();
} }
} }
@ -2087,20 +2114,20 @@ public class DecafParser extends Parser {
RecipientContext _localctx = new RecipientContext(_ctx, getState()); RecipientContext _localctx = new RecipientContext(_ctx, getState());
enterRule(_localctx, 40, RULE_recipient); enterRule(_localctx, 40, RULE_recipient);
try { try {
setState(261); setState(262);
_errHandler.sync(this); _errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) {
case 1: case 1:
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(259); setState(260);
methName(); methName();
} }
break; break;
case 2: case 2:
enterOuterAlt(_localctx, 2); enterOuterAlt(_localctx, 2);
{ {
setState(260); setState(261);
id(); id();
} }
break; break;
@ -2151,21 +2178,21 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(263);
id();
setState(264); setState(264);
id();
setState(265);
match(T__4); match(T__4);
setState(266); setState(267);
_errHandler.sync(this); _errHandler.sync(this);
_la = _input.LA(1); _la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 132216288968736L) != 0)) { if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 132216288968736L) != 0)) {
{ {
setState(265); setState(266);
args(); args();
} }
} }
setState(268); setState(269);
match(T__5); match(T__5);
} }
} }
@ -2214,21 +2241,21 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(270); setState(271);
expr(0); expr(0);
setState(275); setState(276);
_errHandler.sync(this); _errHandler.sync(this);
_la = _input.LA(1); _la = _input.LA(1);
while (_la==T__9) { while (_la==T__9) {
{ {
{ {
setState(271);
match(T__9);
setState(272); setState(272);
match(T__9);
setState(273);
expr(0); expr(0);
} }
} }
setState(277); setState(278);
_errHandler.sync(this); _errHandler.sync(this);
_la = _input.LA(1); _la = _input.LA(1);
} }
@ -2276,7 +2303,7 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(278); setState(279);
_la = _input.LA(1); _la = _input.LA(1);
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 96757023244288L) != 0)) ) { if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 96757023244288L) != 0)) ) {
_errHandler.recoverInline(this); _errHandler.recoverInline(this);
@ -2327,7 +2354,7 @@ public class DecafParser extends Parser {
try { try {
enterOuterAlt(_localctx, 1); enterOuterAlt(_localctx, 1);
{ {
setState(280); setState(281);
match(IDENTIFIER); match(IDENTIFIER);
} }
} }
@ -2352,13 +2379,13 @@ public class DecafParser extends Parser {
private boolean expr_sempred(ExprContext _localctx, int predIndex) { private boolean expr_sempred(ExprContext _localctx, int predIndex) {
switch (predIndex) { switch (predIndex) {
case 0: case 0:
return precpred(_ctx, 7); return precpred(_ctx, 8);
} }
return true; return true;
} }
public static final String _serializedATN = public static final String _serializedATN =
"\u0004\u00011\u011b\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ "\u0004\u00011\u011c\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
"\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+
"\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+
"\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+
@ -2388,32 +2415,32 @@ public class DecafParser extends Parser {
"\r\u0001\r\u0001\r\u0003\r\u00c3\b\r\u0001\r\u0001\r\u0003\r\u00c7\b\r"+ "\r\u0001\r\u0001\r\u0003\r\u00c3\b\r\u0001\r\u0001\r\u0003\r\u00c7\b\r"+
"\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+
"\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+
"\u0003\u000e\u00d5\b\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ "\u0001\u000e\u0003\u000e\u00d6\b\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+
"\u0005\u000e\u00db\b\u000e\n\u000e\f\u000e\u00de\t\u000e\u0001\u000f\u0001"+ "\u0001\u000e\u0005\u000e\u00dc\b\u000e\n\u000e\f\u000e\u00df\t\u000e\u0001"+
"\u000f\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0003\u0011\u00e6"+ "\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0003"+
"\b\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0005\u0011\u00eb\b\u0011"+ "\u0011\u00e7\b\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0005\u0011\u00ec"+
"\n\u0011\f\u0011\u00ee\t\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001"+ "\b\u0011\n\u0011\f\u0011\u00ef\t\u0011\u0001\u0011\u0001\u0011\u0001\u0012"+
"\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0003\u0013\u00f8"+ "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0003\u0013"+
"\b\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0005\u0013\u00fd\b\u0013"+ "\u00f9\b\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0005\u0013\u00fe\b"+
"\n\u0013\f\u0013\u0100\t\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001"+ "\u0013\n\u0013\f\u0013\u0101\t\u0013\u0001\u0013\u0001\u0013\u0001\u0014"+
"\u0014\u0003\u0014\u0106\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0003"+ "\u0001\u0014\u0003\u0014\u0107\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015"+
"\u0015\u010b\b\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001"+ "\u0003\u0015\u010c\b\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016"+
"\u0016\u0005\u0016\u0112\b\u0016\n\u0016\f\u0016\u0115\t\u0016\u0001\u0017"+ "\u0001\u0016\u0005\u0016\u0113\b\u0016\n\u0016\f\u0016\u0116\t\u0016\u0001"+
"\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0000\u0001\u001c\u0019"+ "\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0000\u0001\u001c"+
"\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a"+ "\u0019\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016\u0018"+
"\u001c\u001e \"$&(*,.0\u0000\u0004\u0001\u0000\"%\u0001\u0000\u0017!\u0002"+ "\u001a\u001c\u001e \"$&(*,.0\u0000\u0004\u0001\u0000\"%\u0001\u0000\u0017"+
"\u0000\u0017\u0017&&\u0002\u0000+,..\u0128\u00002\u0001\u0000\u0000\u0000"+ "!\u0002\u0000\u0017\u0017&&\u0002\u0000+,..\u012a\u00002\u0001\u0000\u0000"+
"\u0002D\u0001\u0000\u0000\u0000\u0004J\u0001\u0000\u0000\u0000\u0006N"+ "\u0000\u0002D\u0001\u0000\u0000\u0000\u0004J\u0001\u0000\u0000\u0000\u0006"+
"\u0001\u0000\u0000\u0000\bR\u0001\u0000\u0000\u0000\nX\u0001\u0000\u0000"+ "N\u0001\u0000\u0000\u0000\bR\u0001\u0000\u0000\u0000\nX\u0001\u0000\u0000"+
"\u0000\fZ\u0001\u0000\u0000\u0000\u000ed\u0001\u0000\u0000\u0000\u0010"+ "\u0000\fZ\u0001\u0000\u0000\u0000\u000ed\u0001\u0000\u0000\u0000\u0010"+
"m\u0001\u0000\u0000\u0000\u0012v\u0001\u0000\u0000\u0000\u0014~\u0001"+ "m\u0001\u0000\u0000\u0000\u0012v\u0001\u0000\u0000\u0000\u0014~\u0001"+
"\u0000\u0000\u0000\u0016\u0081\u0001\u0000\u0000\u0000\u0018\u00bb\u0001"+ "\u0000\u0000\u0000\u0016\u0081\u0001\u0000\u0000\u0000\u0018\u00bb\u0001"+
"\u0000\u0000\u0000\u001a\u00c6\u0001\u0000\u0000\u0000\u001c\u00d4\u0001"+ "\u0000\u0000\u0000\u001a\u00c6\u0001\u0000\u0000\u0000\u001c\u00d5\u0001"+
"\u0000\u0000\u0000\u001e\u00df\u0001\u0000\u0000\u0000 \u00e1\u0001\u0000"+ "\u0000\u0000\u0000\u001e\u00e0\u0001\u0000\u0000\u0000 \u00e2\u0001\u0000"+
"\u0000\u0000\"\u00e5\u0001\u0000\u0000\u0000$\u00f1\u0001\u0000\u0000"+ "\u0000\u0000\"\u00e6\u0001\u0000\u0000\u0000$\u00f2\u0001\u0000\u0000"+
"\u0000&\u00f7\u0001\u0000\u0000\u0000(\u0105\u0001\u0000\u0000\u0000*"+ "\u0000&\u00f8\u0001\u0000\u0000\u0000(\u0106\u0001\u0000\u0000\u0000*"+
"\u0107\u0001\u0000\u0000\u0000,\u010e\u0001\u0000\u0000\u0000.\u0116\u0001"+ "\u0108\u0001\u0000\u0000\u0000,\u010f\u0001\u0000\u0000\u0000.\u0117\u0001"+
"\u0000\u0000\u00000\u0118\u0001\u0000\u0000\u000023\u0005\u0013\u0000"+ "\u0000\u0000\u00000\u0119\u0001\u0000\u0000\u000023\u0005\u0013\u0000"+
"\u000034\u0005\u0001\u0000\u000045\u00030\u0018\u000057\u0005\u0002\u0000"+ "\u000034\u0005\u0001\u0000\u000045\u00030\u0018\u000057\u0005\u0002\u0000"+
"\u000068\u0003\u000e\u0007\u000076\u0001\u0000\u0000\u000078\u0001\u0000"+ "\u000068\u0003\u000e\u0007\u000076\u0001\u0000\u0000\u000078\u0001\u0000"+
"\u0000\u00008>\u0001\u0000\u0000\u00009=\u0003\u0002\u0001\u0000:=\u0003"+ "\u0000\u00008>\u0001\u0000\u0000\u00009=\u0003\u0002\u0001\u0000:=\u0003"+
@ -2489,53 +2516,54 @@ public class DecafParser extends Parser {
"\u0000\u00c5\u00c7\u0001\u0000\u0000\u0000\u00c6\u00bd\u0001\u0000\u0000"+ "\u0000\u00c5\u00c7\u0001\u0000\u0000\u0000\u00c6\u00bd\u0001\u0000\u0000"+
"\u0000\u00c6\u00be\u0001\u0000\u0000\u0000\u00c7\u001b\u0001\u0000\u0000"+ "\u0000\u00c6\u00be\u0001\u0000\u0000\u0000\u00c7\u001b\u0001\u0000\u0000"+
"\u0000\u00c8\u00c9\u0006\u000e\uffff\uffff\u0000\u00c9\u00ca\u0003 \u0010"+ "\u0000\u00c8\u00c9\u0006\u000e\uffff\uffff\u0000\u00c9\u00ca\u0003 \u0010"+
"\u0000\u00ca\u00cb\u0003\u001c\u000e\u0006\u00cb\u00d5\u0001\u0000\u0000"+ "\u0000\u00ca\u00cb\u0003\u001c\u000e\u0007\u00cb\u00d6\u0001\u0000\u0000"+
"\u0000\u00cc\u00d5\u0003.\u0017\u0000\u00cd\u00ce\u0005\u0005\u0000\u0000"+ "\u0000\u00cc\u00d6\u0003.\u0017\u0000\u00cd\u00ce\u0005\u0005\u0000\u0000"+
"\u00ce\u00cf\u0003\u001c\u000e\u0000\u00cf\u00d0\u0005\u0006\u0000\u0000"+ "\u00ce\u00cf\u0003\u001c\u000e\u0000\u00cf\u00d0\u0005\u0006\u0000\u0000"+
"\u00d0\u00d5\u0001\u0000\u0000\u0000\u00d1\u00d5\u0003\"\u0011\u0000\u00d2"+ "\u00d0\u00d6\u0001\u0000\u0000\u0000\u00d1\u00d6\u0003\"\u0011\u0000\u00d2"+
"\u00d5\u0003\u001a\r\u0000\u00d3\u00d5\u0005\u0015\u0000\u0000\u00d4\u00c8"+ "\u00d6\u0003\u001a\r\u0000\u00d3\u00d6\u0005\u0016\u0000\u0000\u00d4\u00d6"+
"\u0001\u0000\u0000\u0000\u00d4\u00cc\u0001\u0000\u0000\u0000\u00d4\u00cd"+ "\u0005\u0015\u0000\u0000\u00d5\u00c8\u0001\u0000\u0000\u0000\u00d5\u00cc"+
"\u0001\u0000\u0000\u0000\u00d4\u00d1\u0001\u0000\u0000\u0000\u00d4\u00d2"+ "\u0001\u0000\u0000\u0000\u00d5\u00cd\u0001\u0000\u0000\u0000\u00d5\u00d1"+
"\u0001\u0000\u0000\u0000\u00d4\u00d3\u0001\u0000\u0000\u0000\u00d5\u00dc"+ "\u0001\u0000\u0000\u0000\u00d5\u00d2\u0001\u0000\u0000\u0000\u00d5\u00d3"+
"\u0001\u0000\u0000\u0000\u00d6\u00d7\n\u0007\u0000\u0000\u00d7\u00d8\u0003"+ "\u0001\u0000\u0000\u0000\u00d5\u00d4\u0001\u0000\u0000\u0000\u00d6\u00dd"+
"\u001e\u000f\u0000\u00d8\u00d9\u0003\u001c\u000e\b\u00d9\u00db\u0001\u0000"+ "\u0001\u0000\u0000\u0000\u00d7\u00d8\n\b\u0000\u0000\u00d8\u00d9\u0003"+
"\u0000\u0000\u00da\u00d6\u0001\u0000\u0000\u0000\u00db\u00de\u0001\u0000"+ "\u001e\u000f\u0000\u00d9\u00da\u0003\u001c\u000e\t\u00da\u00dc\u0001\u0000"+
"\u0000\u0000\u00dc\u00da\u0001\u0000\u0000\u0000\u00dc\u00dd\u0001\u0000"+ "\u0000\u0000\u00db\u00d7\u0001\u0000\u0000\u0000\u00dc\u00df\u0001\u0000"+
"\u0000\u0000\u00dd\u001d\u0001\u0000\u0000\u0000\u00de\u00dc\u0001\u0000"+ "\u0000\u0000\u00dd\u00db\u0001\u0000\u0000\u0000\u00dd\u00de\u0001\u0000"+
"\u0000\u0000\u00df\u00e0\u0007\u0001\u0000\u0000\u00e0\u001f\u0001\u0000"+ "\u0000\u0000\u00de\u001d\u0001\u0000\u0000\u0000\u00df\u00dd\u0001\u0000"+
"\u0000\u0000\u00e1\u00e2\u0007\u0002\u0000\u0000\u00e2!\u0001\u0000\u0000"+ "\u0000\u0000\u00e0\u00e1\u0007\u0001\u0000\u0000\u00e1\u001f\u0001\u0000"+
"\u0000\u00e3\u00e4\u0005\u0016\u0000\u0000\u00e4\u00e6\u0005\u0012\u0000"+ "\u0000\u0000\u00e2\u00e3\u0007\u0002\u0000\u0000\u00e3!\u0001\u0000\u0000"+
"\u0000\u00e5\u00e3\u0001\u0000\u0000\u0000\u00e5\u00e6\u0001\u0000\u0000"+ "\u0000\u00e4\u00e5\u0005\u0016\u0000\u0000\u00e5\u00e7\u0005\u0012\u0000"+
"\u0000\u00e6\u00ec\u0001\u0000\u0000\u0000\u00e7\u00e8\u0003(\u0014\u0000"+ "\u0000\u00e6\u00e4\u0001\u0000\u0000\u0000\u00e6\u00e7\u0001\u0000\u0000"+
"\u00e8\u00e9\u0005\u0012\u0000\u0000\u00e9\u00eb\u0001\u0000\u0000\u0000"+ "\u0000\u00e7\u00ed\u0001\u0000\u0000\u0000\u00e8\u00e9\u0003(\u0014\u0000"+
"\u00ea\u00e7\u0001\u0000\u0000\u0000\u00eb\u00ee\u0001\u0000\u0000\u0000"+ "\u00e9\u00ea\u0005\u0012\u0000\u0000\u00ea\u00ec\u0001\u0000\u0000\u0000"+
"\u00ec\u00ea\u0001\u0000\u0000\u0000\u00ec\u00ed\u0001\u0000\u0000\u0000"+ "\u00eb\u00e8\u0001\u0000\u0000\u0000\u00ec\u00ef\u0001\u0000\u0000\u0000"+
"\u00ed\u00ef\u0001\u0000\u0000\u0000\u00ee\u00ec\u0001\u0000\u0000\u0000"+ "\u00ed\u00eb\u0001\u0000\u0000\u0000\u00ed\u00ee\u0001\u0000\u0000\u0000"+
"\u00ef\u00f0\u00030\u0018\u0000\u00f0#\u0001\u0000\u0000\u0000\u00f1\u00f2"+ "\u00ee\u00f0\u0001\u0000\u0000\u0000\u00ef\u00ed\u0001\u0000\u0000\u0000"+
"\u0003\"\u0011\u0000\u00f2\u00f3\u0003\u0006\u0003\u0000\u00f3\u00f4\u0003"+ "\u00f0\u00f1\u00030\u0018\u0000\u00f1#\u0001\u0000\u0000\u0000\u00f2\u00f3"+
"\u001c\u000e\u0000\u00f4%\u0001\u0000\u0000\u0000\u00f5\u00f6\u0005\u0016"+ "\u0003\"\u0011\u0000\u00f3\u00f4\u0003\u0006\u0003\u0000\u00f4\u00f5\u0003"+
"\u0000\u0000\u00f6\u00f8\u0005\u0012\u0000\u0000\u00f7\u00f5\u0001\u0000"+ "\u001c\u000e\u0000\u00f5%\u0001\u0000\u0000\u0000\u00f6\u00f7\u0005\u0016"+
"\u0000\u0000\u00f7\u00f8\u0001\u0000\u0000\u0000\u00f8\u00fe\u0001\u0000"+ "\u0000\u0000\u00f7\u00f9\u0005\u0012\u0000\u0000\u00f8\u00f6\u0001\u0000"+
"\u0000\u0000\u00f9\u00fa\u0003(\u0014\u0000\u00fa\u00fb\u0005\u0012\u0000"+ "\u0000\u0000\u00f8\u00f9\u0001\u0000\u0000\u0000\u00f9\u00ff\u0001\u0000"+
"\u0000\u00fb\u00fd\u0001\u0000\u0000\u0000\u00fc\u00f9\u0001\u0000\u0000"+ "\u0000\u0000\u00fa\u00fb\u0003(\u0014\u0000\u00fb\u00fc\u0005\u0012\u0000"+
"\u0000\u00fd\u0100\u0001\u0000\u0000\u0000\u00fe\u00fc\u0001\u0000\u0000"+ "\u0000\u00fc\u00fe\u0001\u0000\u0000\u0000\u00fd\u00fa\u0001\u0000\u0000"+
"\u0000\u00fe\u00ff\u0001\u0000\u0000\u0000\u00ff\u0101\u0001\u0000\u0000"+ "\u0000\u00fe\u0101\u0001\u0000\u0000\u0000\u00ff\u00fd\u0001\u0000\u0000"+
"\u0000\u0100\u00fe\u0001\u0000\u0000\u0000\u0101\u0102\u0003*\u0015\u0000"+ "\u0000\u00ff\u0100\u0001\u0000\u0000\u0000\u0100\u0102\u0001\u0000\u0000"+
"\u0102\'\u0001\u0000\u0000\u0000\u0103\u0106\u0003*\u0015\u0000\u0104"+ "\u0000\u0101\u00ff\u0001\u0000\u0000\u0000\u0102\u0103\u0003*\u0015\u0000"+
"\u0106\u00030\u0018\u0000\u0105\u0103\u0001\u0000\u0000\u0000\u0105\u0104"+ "\u0103\'\u0001\u0000\u0000\u0000\u0104\u0107\u0003*\u0015\u0000\u0105"+
"\u0001\u0000\u0000\u0000\u0106)\u0001\u0000\u0000\u0000\u0107\u0108\u0003"+ "\u0107\u00030\u0018\u0000\u0106\u0104\u0001\u0000\u0000\u0000\u0106\u0105"+
"0\u0018\u0000\u0108\u010a\u0005\u0005\u0000\u0000\u0109\u010b\u0003,\u0016"+ "\u0001\u0000\u0000\u0000\u0107)\u0001\u0000\u0000\u0000\u0108\u0109\u0003"+
"\u0000\u010a\u0109\u0001\u0000\u0000\u0000\u010a\u010b\u0001\u0000\u0000"+ "0\u0018\u0000\u0109\u010b\u0005\u0005\u0000\u0000\u010a\u010c\u0003,\u0016"+
"\u0000\u010b\u010c\u0001\u0000\u0000\u0000\u010c\u010d\u0005\u0006\u0000"+ "\u0000\u010b\u010a\u0001\u0000\u0000\u0000\u010b\u010c\u0001\u0000\u0000"+
"\u0000\u010d+\u0001\u0000\u0000\u0000\u010e\u0113\u0003\u001c\u000e\u0000"+ "\u0000\u010c\u010d\u0001\u0000\u0000\u0000\u010d\u010e\u0005\u0006\u0000"+
"\u010f\u0110\u0005\n\u0000\u0000\u0110\u0112\u0003\u001c\u000e\u0000\u0111"+ "\u0000\u010e+\u0001\u0000\u0000\u0000\u010f\u0114\u0003\u001c\u000e\u0000"+
"\u010f\u0001\u0000\u0000\u0000\u0112\u0115\u0001\u0000\u0000\u0000\u0113"+ "\u0110\u0111\u0005\n\u0000\u0000\u0111\u0113\u0003\u001c\u000e\u0000\u0112"+
"\u0111\u0001\u0000\u0000\u0000\u0113\u0114\u0001\u0000\u0000\u0000\u0114"+ "\u0110\u0001\u0000\u0000\u0000\u0113\u0116\u0001\u0000\u0000\u0000\u0114"+
"-\u0001\u0000\u0000\u0000\u0115\u0113\u0001\u0000\u0000\u0000\u0116\u0117"+ "\u0112\u0001\u0000\u0000\u0000\u0114\u0115\u0001\u0000\u0000\u0000\u0115"+
"\u0007\u0003\u0000\u0000\u0117/\u0001\u0000\u0000\u0000\u0118\u0119\u0005"+ "-\u0001\u0000\u0000\u0000\u0116\u0114\u0001\u0000\u0000\u0000\u0117\u0118"+
"-\u0000\u0000\u01191\u0001\u0000\u0000\u0000\u00197<>DRX_q{\u0084\u0086"+ "\u0007\u0003\u0000\u0000\u0118/\u0001\u0000\u0000\u0000\u0119\u011a\u0005"+
"\u0092\u00ab\u00bb\u00c2\u00c6\u00d4\u00dc\u00e5\u00ec\u00f7\u00fe\u0105"+ "-\u0000\u0000\u011a1\u0001\u0000\u0000\u0000\u00197<>DRX_q{\u0084\u0086"+
"\u010a\u0113"; "\u0092\u00ab\u00bb\u00c2\u00c6\u00d5\u00dd\u00e6\u00ed\u00f8\u00ff\u0106"+
"\u010b\u0114";
public static final ATN _ATN = public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray()); new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static { static {

View File

@ -1,4 +1,4 @@
// Generated from C:/dev/Pressmium/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1 // Generated from C:/Users/laure/Documents/Dev/Compilerbau/Projekt/CompilerULTIMATE/src/main/antlr/Decaf.g4 by ANTLR 4.13.1
package de.maishai.antlr; package de.maishai.antlr;
import org.antlr.v4.runtime.tree.ParseTreeVisitor; import org.antlr.v4.runtime.tree.ParseTreeVisitor;
@ -201,6 +201,13 @@ public interface DecafVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result * @return the visitor result
*/ */
T visitBinaryOperation(DecafParser.BinaryOperationContext ctx); T visitBinaryOperation(DecafParser.BinaryOperationContext ctx);
/**
* Visit a parse tree produced by the {@code This}
* labeled alternative in {@link DecafParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitThis(DecafParser.ThisContext ctx);
/** /**
* Visit a parse tree produced by the {@code StatementExpressionexpr} * Visit a parse tree produced by the {@code StatementExpressionexpr}
* labeled alternative in {@link DecafParser#expr}. * labeled alternative in {@link DecafParser#expr}.

View File

@ -1,5 +1,5 @@
package de.maishai.ast.records; package de.maishai.ast.records;
public sealed interface Expression extends Node permits Binary, BoolLiteral, CharLiteral, FieldVarAccess, IntLiteral, MethodCall, New, Unary { public sealed interface Expression extends Node permits Binary, BoolLiteral, CharLiteral, FieldVarAccess, IntLiteral, MethodCall, New, Null, This, Unary {
} }

View File

@ -1,4 +1,4 @@
package de.maishai.ast.records; package de.maishai.ast.records;
public sealed interface Node permits Block, Class, Constructor, Expression, Declaration, Method, Parameter, Statement { public sealed interface Node permits Block, Class, Constructor, Declaration, Expression, Method, Parameter, Program, Statement {
} }

View File

@ -0,0 +1,5 @@
package de.maishai.ast.records;
public record Null() implements Expression {
}

View File

@ -0,0 +1,6 @@
package de.maishai.ast.records;
import java.util.List;
public record Program(List<Class> classes) implements Node {
}

View File

@ -0,0 +1,5 @@
package de.maishai.ast.records;
public record This() implements Expression {
}

View File

@ -1,53 +1,50 @@
package de.maishai.typedast.Help; package de.maishai.typedast.Help;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.typedast.Type;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.typedclass.*; import de.maishai.typedast.typedclass.*;
import java.util.Map;
public class TypedExpressionHelp { public class TypedExpressionHelp {
public static TypedExpression convertExpression( TypedClass clas, Expression expression) { public static TypedExpression convertExpression( TypedProgram typedProgram, Expression expression) {
if (expression instanceof BoolLiteral boolLiteral) { if (expression instanceof BoolLiteral boolLiteral) {
TypedBoolLiteral typedBoolLiteral = new TypedBoolLiteral( clas, boolLiteral); TypedBoolLiteral typedBoolLiteral = new TypedBoolLiteral( typedProgram, boolLiteral);
typedBoolLiteral.typeCheck( clas); typedBoolLiteral.typeCheck( typedProgram);
return typedBoolLiteral; return typedBoolLiteral;
} }
else if (expression instanceof CharLiteral charLiteral) { else if (expression instanceof CharLiteral charLiteral) {
TypedCharLiteral typedCharLiteral = new TypedCharLiteral( clas, charLiteral); TypedCharLiteral typedCharLiteral = new TypedCharLiteral( typedProgram, charLiteral);
typedCharLiteral.typeCheck( clas); typedCharLiteral.typeCheck( typedProgram);
return typedCharLiteral; return typedCharLiteral;
} }
else if (expression instanceof IntLiteral intLiteral) { else if (expression instanceof IntLiteral intLiteral) {
TypedIntLiteral typedIntLiteral = new TypedIntLiteral( clas, intLiteral); TypedIntLiteral typedIntLiteral = new TypedIntLiteral( typedProgram, intLiteral);
typedIntLiteral.typeCheck( clas); typedIntLiteral.typeCheck( typedProgram);
return typedIntLiteral; return typedIntLiteral;
} }
else if (expression instanceof Binary binary) { else if (expression instanceof Binary binary) {
TypedBinary typedBinary = new TypedBinary( clas, binary); TypedBinary typedBinary = new TypedBinary( typedProgram, binary);
typedBinary.typeCheck( clas); typedBinary.typeCheck( typedProgram);
return typedBinary; return typedBinary;
} }
else if (expression instanceof FieldVarAccess fieldVarAccess) { else if (expression instanceof FieldVarAccess fieldVarAccess) {
TypedFieldVarAccess typedFieldVarAccess = new TypedFieldVarAccess( clas, fieldVarAccess); TypedFieldVarAccess typedFieldVarAccess = new TypedFieldVarAccess( typedProgram, fieldVarAccess);
typedFieldVarAccess.typeCheck( clas); typedFieldVarAccess.typeCheck( typedProgram);
return typedFieldVarAccess; return typedFieldVarAccess;
} }
else if (expression instanceof MethodCall methodCall) { else if (expression instanceof MethodCall methodCall) {
TypedMethodCall typedMethodCall = new TypedMethodCall( clas, methodCall); TypedMethodCall typedMethodCall = new TypedMethodCall( typedProgram, methodCall);
typedMethodCall.typeCheck( clas); typedMethodCall.typeCheck(typedProgram);
return typedMethodCall; return typedMethodCall;
} }
else if (expression instanceof New newStmt) { else if (expression instanceof New newStmt) {
TypedNew typedNew = new TypedNew( clas, newStmt); TypedNew typedNew = new TypedNew( typedProgram, newStmt);
typedNew.typeCheck( clas); typedNew.typeCheck( typedProgram);
return typedNew; return typedNew;
} }
else if (expression instanceof Unary unary) { else if (expression instanceof Unary unary) {
TypedUnary typedUnary = new TypedUnary( clas, unary); TypedUnary typedUnary = new TypedUnary( typedProgram, unary);
typedUnary.typeCheck( clas); typedUnary.typeCheck( typedProgram);
return typedUnary; return typedUnary;
} else { } else {
return null; return null;

View File

@ -12,7 +12,7 @@ public class Type {
} }
private final Kind kind; private final Kind kind;
private final String reference; private final String reference;
public Type(Kind kind, String reference){ private Type(Kind kind, String reference){
this.kind = kind; this.kind = kind;
this.reference = reference; this.reference = reference;
} }

View File

@ -1,7 +1,7 @@
package de.maishai.typedast; package de.maishai.typedast;
import de.maishai.typedast.typedclass.TypedClass; import de.maishai.typedast.typedclass.TypedProgram;
public interface TypedNode { public interface TypedNode {
Type typeCheck(TypedClass clas); Type typeCheck(TypedProgram typedProgram);
} }

View File

@ -1,59 +1,37 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Assignment; import de.maishai.ast.records.Assignment;
import de.maishai.ast.records.Expression;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedStatement; import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@AllArgsConstructor
public class TypedAssignment implements TypedStatement { public class TypedAssignment implements TypedStatement {
private TypedExpression value; private TypedExpression value;
private TypedFieldVarAccess location; private TypedFieldVarAccess location;
private Type type; private Type type;
public TypedAssignment(TypedClass clas, Assignment untyped) { public TypedAssignment(TypedProgram typedProgram, Assignment untyped) {
convertToTypedAssignment(clas, untyped); convertToTypedAssignment(typedProgram, untyped);
} }
public void convertToTypedAssignment(TypedClass clas, Assignment untyped) { public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
value = convertExpression(clas, untyped.value()); value = convertExpression(typedProgram, untyped.value());
location = new TypedFieldVarAccess(clas, untyped.location()); location = new TypedFieldVarAccess(typedProgram, untyped.location());
location.typeCheck(clas);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
Type typeLeft = null;
if (clas.isThereField(location.getName())) { Type typeLeft = getTypeLeft(typedProgram);
typeLeft = clas.getFieldType(location.getName()); Type typeRight = value.typeCheck(typedProgram);
} else {
if (clas.isCurrentMethodPresent() && !clas.isCurrentConstructorPresent()) {
if (clas.getCurrentMethod().isLocalVariableInMethod(location.getName())) {
typeLeft = clas.getCurrentMethod().getLocalVariableType(location.getName());
} else {
throw new RuntimeException("Variable " + location.getName() + " not declared in method");
}
}
if (!clas.isCurrentMethodPresent() && clas.isCurrentConstructorPresent()) {
if (clas.getCurrentConstructor().isLocalVariableInConstructor(location.getName())) {
typeLeft = clas.getCurrentConstructor().getLocalVariableType(location.getName());
} else {
throw new RuntimeException("Variable " + location.getName() + " not declared in constructor");
}
}
}
Type typeRight = value.typeCheck(clas);
if (typeLeft.equals(typeRight)) { if (typeLeft.equals(typeRight)) {
type = typeLeft; type = typeLeft;
@ -62,6 +40,45 @@ public class TypedAssignment implements TypedStatement {
throw new RuntimeException("type of left not equals with type of right"); throw new RuntimeException("type of left not equals with type of right");
} }
private Type getTypeLeft(TypedProgram typedProgram) {
String name = location.getName();
TypedClass currentClass = typedProgram.getCurrentClass();
if (currentClass.isThereField(name) && location.getField()) {
return currentClass.getFieldType(name);
}
if (currentClass.isCurrentMethodPresent() && !currentClass.isCurrentConstructorPresent()) {
return getTypeFromMethodOrField(currentClass.getCurrentMethod(), name, currentClass);
}
if (!currentClass.isCurrentMethodPresent() && currentClass.isCurrentConstructorPresent()) {
return getTypeFromConstructorOrField(currentClass.getCurrentConstructor(), name, currentClass);
}
throw new RuntimeException("Variable " + name + " not declared");
}
private Type getTypeFromMethodOrField(TypedMethod currentMethod, String name, TypedClass currentClass) {
if (currentMethod.isLocalVariableInMethod(name)) {
return currentMethod.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) {
return currentClass.getFieldType(name);
} else {
throw new RuntimeException("Variable " + name + " not declared in method");
}
}
private Type getTypeFromConstructorOrField(TypedConstructor currentConstructor, String name, TypedClass currentClass) {
if (currentConstructor.isLocalVariableInConstructor(name)) {
return currentConstructor.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) {
return currentClass.getFieldType(name);
} else {
throw new RuntimeException("Variable " + name + " not declared in constructor");
}
}
@Override @Override
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
if(value instanceof TypedNew) { if(value instanceof TypedNew) {

View File

@ -5,6 +5,7 @@ import de.maishai.ast.records.Binary;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
@ -17,26 +18,27 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor
public class TypedBinary implements TypedExpression { public class TypedBinary implements TypedExpression {
private TypedExpression left; private TypedExpression left;
private Operator op; private Operator op;
private TypedExpression right; private TypedExpression right;
private Type type; private Type type;
public TypedBinary(TypedClass clas, Binary unTypedBinary) { public TypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
convertToTypedBinary(clas, unTypedBinary); convertToTypedBinary(typedProgram, unTypedBinary);
} }
public void convertToTypedBinary(TypedClass clas, Binary unTypedBinary) { public void convertToTypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
left = convertExpression(clas, unTypedBinary.left()); left = convertExpression(typedProgram, unTypedBinary.left());
right = convertExpression(clas, unTypedBinary.right()); right = convertExpression(typedProgram, unTypedBinary.right());
op = unTypedBinary.op(); op = unTypedBinary.op();
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
Type leftType = left.typeCheck(clas); Type leftType = left.typeCheck(typedProgram);
Type rightType = right.typeCheck(clas); Type rightType = right.typeCheck(typedProgram);
if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) { if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) {
if (leftType == Type.INT && rightType == Type.INT) { if (leftType == Type.INT && rightType == Type.INT) {

View File

@ -8,11 +8,9 @@ import de.maishai.typedast.TypedStatement;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ -23,8 +21,8 @@ public class TypedBlock implements TypedNode {
private Type type; private Type type;
public TypedBlock(TypedClass clas, Block unTypedBlock) { public TypedBlock(TypedProgram typedProgram, Block unTypedBlock) {
convertToTypedBlock(clas, unTypedBlock); convertToTypedBlock(typedProgram, unTypedBlock);
} }
public TypedBlock(List<TypedLocalVariable> vars, List<TypedStatement> stmts) { public TypedBlock(List<TypedLocalVariable> vars, List<TypedStatement> stmts) {
@ -32,56 +30,56 @@ public class TypedBlock implements TypedNode {
this.stmts = stmts; this.stmts = stmts;
} }
public void convertToTypedBlock(TypedClass clas, Block unTypedBlock) { public void convertToTypedBlock(TypedProgram typedProgram, Block unTypedBlock) {
if (unTypedBlock == null) { if (unTypedBlock == null) {
return; return;
} }
for (Declaration var : unTypedBlock.localVariables()) { for (Declaration var : unTypedBlock.localVariables()) {
vars.add(new TypedLocalVariable(clas, var)); vars.add(new TypedLocalVariable(typedProgram, var));
} }
for (var stmt : unTypedBlock.stmts()) { for (var stmt : unTypedBlock.stmts()) {
if (stmt instanceof Assignment assignment) { if (stmt instanceof Assignment assignment) {
TypedAssignment typedAssignment = new TypedAssignment(clas, assignment); TypedAssignment typedAssignment = new TypedAssignment(typedProgram, assignment);
typedAssignment.typeCheck(clas); typedAssignment.typeCheck(typedProgram);
stmts.add(typedAssignment); stmts.add(typedAssignment);
continue; continue;
} }
if (stmt instanceof For forStmt) { if (stmt instanceof For forStmt) {
TypedFor typedFor = new TypedFor(clas, forStmt); TypedFor typedFor = new TypedFor(typedProgram, forStmt);
typedFor.typeCheck(clas); typedFor.typeCheck(typedProgram);
stmts.add(typedFor); stmts.add(typedFor);
continue; continue;
} }
if (stmt instanceof IfElse ifElse) { if (stmt instanceof IfElse ifElse) {
TypedIfElse typedIfElse = new TypedIfElse(clas, ifElse); TypedIfElse typedIfElse = new TypedIfElse(typedProgram, ifElse);
typedIfElse.typeCheck(clas); typedIfElse.typeCheck(typedProgram);
stmts.add(typedIfElse); stmts.add(typedIfElse);
continue; continue;
} }
if (stmt instanceof While whileStmt) { if (stmt instanceof While whileStmt) {
TypedWhile typedWhile = new TypedWhile(clas, whileStmt); TypedWhile typedWhile = new TypedWhile(typedProgram, whileStmt);
typedWhile.typeCheck(clas); typedWhile.typeCheck(typedProgram);
stmts.add(typedWhile); stmts.add(typedWhile);
continue; continue;
} }
if (stmt instanceof DoWhile doWhile) { if (stmt instanceof DoWhile doWhile) {
TypedDoWhile typedDoWhile = new TypedDoWhile(clas, doWhile); TypedDoWhile typedDoWhile = new TypedDoWhile(typedProgram, doWhile);
typedDoWhile.typeCheck(clas); typedDoWhile.typeCheck(typedProgram);
stmts.add(typedDoWhile); stmts.add(typedDoWhile);
continue; continue;
} }
if (stmt instanceof Return returnStmt) { if (stmt instanceof Return returnStmt) {
TypedReturn typedReturn = new TypedReturn(clas, returnStmt); TypedReturn typedReturn = new TypedReturn(typedProgram, returnStmt);
typedReturn.typeCheck(clas); typedReturn.typeCheck(typedProgram);
stmts.add(typedReturn); stmts.add(typedReturn);
continue; continue;
} }
if (stmt instanceof New newStmt) { if (stmt instanceof New newStmt) {
TypedNew typedNew = new TypedNew(clas, newStmt); TypedNew typedNew = new TypedNew(typedProgram, newStmt);
typedNew.typeCheck(clas); typedNew.typeCheck(typedProgram);
stmts.add(typedNew); stmts.add(typedNew);
continue; continue;
} }
@ -92,25 +90,25 @@ public class TypedBlock implements TypedNode {
} }
if (stmt instanceof MethodCall methodCall) { if (stmt instanceof MethodCall methodCall) {
TypedMethodCall typedMethodCall = new TypedMethodCall(clas, methodCall); TypedMethodCall typedMethodCall = new TypedMethodCall(typedProgram, methodCall);
typedMethodCall.typeCheck(clas); typedMethodCall.typeCheck(typedProgram);
stmts.add(typedMethodCall); stmts.add(typedMethodCall);
} }
} }
this.typeCheck(clas); this.typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
Type chekType = null; Type chekType = null;
for (TypedStatement stmt : stmts) { for (TypedStatement stmt : stmts) {
stmt.typeCheck(clas); stmt.typeCheck(typedProgram);
if(stmt instanceof TypedReturn returnStmt) { if (stmt instanceof TypedReturn returnStmt) {
chekType = returnStmt.getType(); chekType = returnStmt.getType();
} }
} }
if(chekType == null) { if (chekType == null) {
chekType = Type.VOID; chekType = Type.VOID;
} }
type = chekType; type = chekType;

View File

@ -1,18 +1,13 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.BoolLiteral; import de.maishai.ast.records.BoolLiteral;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class TypedBoolLiteral implements TypedExpression { public class TypedBoolLiteral implements TypedExpression {
@ -21,25 +16,25 @@ public class TypedBoolLiteral implements TypedExpression {
private Type type; private Type type;
public TypedBoolLiteral(TypedClass clas, BoolLiteral unTypedBoolLiteral) { public TypedBoolLiteral(TypedProgram typedProgram, BoolLiteral unTypedBoolLiteral) {
convertToTypedBoolLiteral(clas, unTypedBoolLiteral); convertToTypedBoolLiteral(typedProgram, unTypedBoolLiteral);
} }
public void convertToTypedBoolLiteral(TypedClass clas, BoolLiteral unTypedBoolLiteral) { public void convertToTypedBoolLiteral(TypedProgram typedProgram, BoolLiteral unTypedBoolLiteral) {
value = unTypedBoolLiteral.value(); value = unTypedBoolLiteral.value();
type = Type.BOOL; type = Type.BOOL;
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }
@Override @Override
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
if(value){ if (value) {
ctx.getMv().visitInsn(Opcodes.ICONST_1); ctx.getMv().visitInsn(Opcodes.ICONST_1);
}else{ } else {
ctx.getMv().visitInsn(Opcodes.ICONST_0); ctx.getMv().visitInsn(Opcodes.ICONST_0);
} }
ctx.pushInstantToStack(); ctx.pushInstantToStack();

View File

@ -1,26 +1,17 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Break; import de.maishai.ast.records.Break;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.TypedStatement; import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
@Data @Data
public class TypedBreak implements TypedStatement { public class TypedBreak implements TypedStatement {
private Type type = Type.VOID; private Type type = Type.VOID;
public TypedBreak convertToTypedBreak(TypedClass clas, Break unTypedBreak) {
return this;
}
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -1,32 +1,27 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.CharLiteral; import de.maishai.ast.records.CharLiteral;
import de.maishai.ast.records.Node;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
@Data @Data
public class TypedCharLiteral implements TypedExpression { public class TypedCharLiteral implements TypedExpression {
private char value; private char value;
private Type type; private Type type;
public TypedCharLiteral(TypedClass clas, CharLiteral unTypedCharLiteral) { public TypedCharLiteral(TypedProgram typedProgram, CharLiteral unTypedCharLiteral) {
convertToCharLiteral(clas, unTypedCharLiteral); convertToCharLiteral(typedProgram, unTypedCharLiteral);
} }
public void convertToCharLiteral(TypedClass clas, CharLiteral unTypedCharLiteral) { public void convertToCharLiteral(TypedProgram typedProgram, CharLiteral unTypedCharLiteral) {
value = unTypedCharLiteral.value(); value = unTypedCharLiteral.value();
type = Type.CHAR; type = Type.CHAR;
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -14,9 +14,7 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -31,43 +29,8 @@ public class TypedClass implements TypedNode {
private Type type; private Type type;
public TypedClass(Class c) { public TypedClass(Class c) {
convertToTypedClass(c); className = c.classname();
} type = Type.REFERENCE(className);
public void enterCurrentMethod(TypedMethod method) {
currentMethod = method;
}
public void exitCurrentMethod() {
currentMethod = null;
}
public void enterCurrentConstructor(TypedConstructor constructor) {
currentConstructor = constructor;
}
public void exitCurrentConstructor() {
currentConstructor = null;
}
public boolean isCurrentMethodPresent() {
return currentMethod != null;
}
public boolean isCurrentConstructorPresent() {
return currentConstructor != null;
}
public boolean isParameterNameInCurrentMethod(String parameterName) {
if (currentMethod == null) {
return false;
}
for (TypedParameter p : currentMethod.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) {
return true;
}
}
return false;
} }
public boolean isParameterNameInCurrentConstructor(String parameterName) { public boolean isParameterNameInCurrentConstructor(String parameterName) {
@ -82,28 +45,27 @@ public class TypedClass implements TypedNode {
return false; return false;
} }
public void convertToTypedClass(Class c) { public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
className = c.classname();
type = Type.REFERENCE(className);
// Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt. // Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt.
// damit die Methoden verwendet werden können, bevor deren Blöcke ausgeführt werden // damit die Methoden verwendet werden können, bevor deren Blöcke ausgeführt werden
for (Declaration declaration : c.fieldDeclarations()) { for (Declaration declaration : c.fieldDeclarations()) {
typedDeclarations.add(new TypedDeclaration(this, declaration)); typedDeclarations.add(new TypedDeclaration(typedProgram, declaration));
} }
for (Constructor constructor : c.constructors()) { for (Constructor constructor : c.constructors()) {
typedConstructors.add(new TypedConstructor(this, constructor)); typedConstructors.add(new TypedConstructor(typedProgram, constructor));
} }
for (Method method : c.methods()) { for (Method method : c.methods()) {
typedMethods.add(new TypedMethod(this, method)); typedMethods.add(new TypedMethod(typedProgram, method));
}
} }
public void covertBlocksOfConstructorsAndMethods(TypedProgram typedProgram, Class c) {
// Hier werden die Blöcke der Konstruktoren ausgeführt // Hier werden die Blöcke der Konstruktoren ausgeführt
int i = 0; int i = 0;
for (Constructor constructor : c.constructors()) { for (Constructor constructor : c.constructors()) {
enterCurrentConstructor(typedConstructors.get(i)); enterCurrentConstructor(typedConstructors.get(i));
typedConstructors.get(i).convertToBlock(this, constructor); typedConstructors.get(i).convertToBlock(typedProgram, constructor);
exitCurrentConstructor(); exitCurrentConstructor();
i++; i++;
} }
@ -111,24 +73,17 @@ public class TypedClass implements TypedNode {
int j = 0; int j = 0;
for (Method method : c.methods()) { for (Method method : c.methods()) {
enterCurrentMethod(typedMethods.get(j)); enterCurrentMethod(typedMethods.get(j));
typedMethods.get(j).convertToTypedBlock(this, method); typedMethods.get(j).convertToTypedBlock(typedProgram, method);
exitCurrentMethod(); exitCurrentMethod();
j++; j++;
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }
public TypedNode startConversion(Class c) {
Map<String, Type> local = new HashMap<>();
return new TypedClass(c);
}
public boolean isParameterWitNameInMethod(String parameterName) { public boolean isParameterWitNameInMethod(String parameterName) {
for (TypedMethod m : typedMethods) { for (TypedMethod m : typedMethods) {
for (TypedParameter p : m.getTypedParameters()) { for (TypedParameter p : m.getTypedParameters()) {
@ -162,6 +117,24 @@ public class TypedClass implements TypedNode {
return null; return null;
} }
public boolean isMethodOfCurrentClass(String methodName) {
for (TypedMethod m : typedMethods) {
if (m.getName().equals(methodName)) {
return true;
}
}
return false;
}
public Type getMethodType(String methodName) {
for (TypedMethod m : typedMethods) {
if (m.getName().equals(methodName)) {
return m.getReturnType();
}
}
return null;
}
public Type getParameterTypeInCurrentConstructor(String parameterName) { public Type getParameterTypeInCurrentConstructor(String parameterName) {
for (TypedParameter p : currentConstructor.getTypedParameters()) { for (TypedParameter p : currentConstructor.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) { if (p.getParaName().equals(parameterName)) {
@ -189,13 +162,28 @@ public class TypedClass implements TypedNode {
return null; return null;
} }
public Type getMethodType(String methodName) { public void enterCurrentMethod(TypedMethod method) {
for (TypedMethod m : typedMethods) { currentMethod = method;
if (m.getName().equals(methodName)) {
return m.getReturnType();
} }
public void exitCurrentMethod() {
currentMethod = null;
} }
return null;
public void enterCurrentConstructor(TypedConstructor constructor) {
currentConstructor = constructor;
}
public void exitCurrentConstructor() {
currentConstructor = null;
}
public boolean isCurrentMethodPresent() {
return currentMethod != null;
}
public boolean isCurrentConstructorPresent() {
return currentConstructor != null;
} }

View File

@ -29,8 +29,8 @@ public class TypedConstructor implements TypedNode {
this.typedBlock = typedBlock; this.typedBlock = typedBlock;
} }
public TypedConstructor(TypedClass clas, Constructor unTypedConstructor) { public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
convertToTypedConstructor(clas, unTypedConstructor); convertToTypedConstructor(typedProgram, unTypedConstructor);
} }
public boolean isLocalVariablePresent(String localVarName) { public boolean isLocalVariablePresent(String localVarName) {
@ -49,23 +49,32 @@ public class TypedConstructor implements TypedNode {
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType(); return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
} }
public void convertToTypedConstructor(TypedClass clas, Constructor unTypedConstructor) { public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
name = unTypedConstructor.className(); name = unTypedConstructor.className();
for (Parameter param : unTypedConstructor.params()) { for (Parameter param : unTypedConstructor.params()) {
typedParameters.add(new TypedParameter(clas, param)); TypedParameter typedParameter = new TypedParameter(typedProgram, param);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
} }
type = Type.VOID; type = Type.VOID;
} }
public void convertToBlock(TypedClass clas, Constructor unTypedConstructor) { public void checkIfParameterExists(String paraName) {
this.typedBlock = new TypedBlock(clas, unTypedConstructor.block()); if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) {
typeCheck(clas); throw new RuntimeException("Parameter " + paraName + " already exists");
}
}
public void convertToBlock(TypedProgram typedProgram, Constructor unTypedConstructor) {
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(typedProgram);
if (type != Type.VOID) { if (type != Type.VOID) {
throw new RuntimeException("Constructor must not habe a return statement"); throw new RuntimeException("Constructor must not habe a return statement");
} }

View File

@ -1,19 +1,14 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Declaration; import de.maishai.ast.records.Declaration;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode; import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Type.Kind.REFERENCE;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -22,39 +17,29 @@ public final class TypedDeclaration implements TypedNode {
private String name; private String name;
private Type type; private Type type;
public TypedDeclaration(TypedClass clas, Declaration declaration) { public TypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
convertToTypedDeclaration(clas, declaration); convertToTypedDeclaration(typedProgram, declaration);
} }
public void convertToTypedDeclaration(TypedClass clas, Declaration declaration) { public void convertToTypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
name = declaration.name(); name = declaration.name();
type = declaration.type(); type = declaration.type();
typeCheck(clas); typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isThereField(name)) { if (type.getReference() != null && !typedProgram.getCurrentClass().getClassName().equals(type.getReference())) {
if (!typedProgram.isTypedClassPresent(type.getReference())) {
throw new RuntimeException("Type " + type.getReference() + " not found");
}
}
if (typedProgram.getCurrentClass().isThereField(name)) {
throw new RuntimeException("Field " + name + " already declared"); throw new RuntimeException("Field " + name + " already declared");
} }
if (type.getKind() == REFERENCE) {
if (!type.getReference().equals(clas.getClassName())) {
throw new RuntimeException("Field " + name + " has wrong type");
}
}
return type; return type;
} }
/*
public void codeGen(MethodVisitor mv, MethodContext ctx) {
System.out.println("Generating code for local variable " + name);
int index = ctx.addVariable(name);
mv.visitLocalVariable(name, type.getDescriptor(), null, ctx.getStartLabel(), ctx.getEndLabel(), index);
}
*/
public void codeGen(ClassWriter cw) { public void codeGen(ClassWriter cw) {
int access = Opcodes.ACC_PUBLIC; // laut Andi ist es ok, dass alle Felder public sind int access = Opcodes.ACC_PUBLIC; // laut Andi ist es ok, dass alle Felder public sind
cw.visitField(access, name, type.getDescriptor(), null, null).visitEnd(); cw.visitField(access, name, type.getDescriptor(), null, null).visitEnd();

View File

@ -3,9 +3,6 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -15,21 +12,21 @@ public class TypedDoWhile implements TypedStatement {
private TypedExpression cond; private TypedExpression cond;
private Type type; private Type type;
public TypedDoWhile(TypedClass clas, DoWhile unTypedDoWhile) { public TypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
convertToTypedDoWhile(clas, unTypedDoWhile); convertToTypedDoWhile(typedProgram, unTypedDoWhile);
} }
public void convertToTypedDoWhile(TypedClass clas, DoWhile unTypedDoWhile) { public void convertToTypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
typedBlock = new TypedBlock(clas, unTypedDoWhile.block()); typedBlock = new TypedBlock(typedProgram, unTypedDoWhile.block());
cond = convertExpression(clas, unTypedDoWhile.cond()); cond = convertExpression(typedProgram, unTypedDoWhile.cond());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (cond.typeCheck(clas) != Type.BOOL) { if (cond.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("Condition must be boolean"); throw new RuntimeException("Condition must be boolean");
} }
typedBlock.typeCheck(clas); typedBlock.typeCheck(typedProgram);
this.type = Type.VOID; this.type = Type.VOID;
return Type.VOID; return Type.VOID;
} }

View File

@ -4,6 +4,7 @@ import de.maishai.ast.records.*;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@ -15,64 +16,92 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor
public class TypedFieldVarAccess implements TypedExpression { public class TypedFieldVarAccess implements TypedExpression {
private Boolean field; private Boolean field;
private TypedExpression recursiveOwnerChain; private TypedExpression recursiveOwnerChain;
private String name; private String name;
private Type type; private Type type;
public TypedFieldVarAccess(TypedClass clas, FieldVarAccess unTypedFieldVarAccess) { public TypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
convertToTypedFieldVarAccess(clas, unTypedFieldVarAccess); convertToTypedFieldVarAccess(typedProgram, unTypedFieldVarAccess);
} }
public void convertToTypedFieldVarAccess(TypedClass clas, FieldVarAccess unTypedFieldVarAccess) { public void convertToTypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
field = unTypedFieldVarAccess.field(); field = unTypedFieldVarAccess.field();
recursiveOwnerChain = convertExpression(clas, unTypedFieldVarAccess.recursiveOwnerChain()); recursiveOwnerChain = convertExpression(typedProgram, unTypedFieldVarAccess.recursiveOwnerChain());
name = unTypedFieldVarAccess.id(); name = unTypedFieldVarAccess.id();
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (field) { if (field) {
if (clas.isThereField(name)) { type = checkFieldOrMethodType(typedProgram);
type = clas.getFieldType(name); return type;
return clas.getFieldType(name);
}else{
throw new RuntimeException("Field " + name + " not declared ");
}
} else { } else {
if (clas.isCurrentConstructorPresent()) { type = checkVariableType(typedProgram);
if (clas.isParameterNameInCurrentConstructor(name)) {
type = clas.getParameterTypeInCurrentConstructor(name);
return type;
} else if (clas.getCurrentConstructor().isLocalVariablePresent(name)) {
type = clas.getCurrentConstructor().getLocalVariableType(name);
return type;
} else if(clas.isThereField(name)){
type = clas.getFieldType(name);
return type; return type;
} }
else {
throw new RuntimeException("Variable " + name + " not declared in constructor");
} }
} else if (clas.isCurrentMethodPresent()) { private Type checkFieldOrMethodType(TypedProgram typedProgram) {
if (clas.isParameterWitNameInMethod(name)) { if (typedProgram.getCurrentClass().isThereField(name)) {
type = clas.getParameterTypeInCurrentMethod(name); type = typedProgram.getCurrentClass().getFieldType(name);
return type; return type;
} else if (clas.getCurrentMethod().isLocalVariablePresent(name)) { } else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = clas.getCurrentMethod().getLocalVariableType(name); type = typedProgram.getCurrentClass().getMethodType(name);
return type; return type;
} else if(clas.isThereField(name)){ } else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
type = clas.getFieldType(name); type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
return type;
} else {
throw new RuntimeException("Field " + name + " not declared");
}
}
private Type checkVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
return checkConstructorVariableType(typedProgram);
} else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
return checkMethodVariableType(typedProgram);
} else {
throw new RuntimeException("Variable " + name + " not declared");
}
}
private Type checkConstructorVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name);
} else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name);
} else {
return checkFieldOrMethodOrRecursiveType(typedProgram);
}
return type; return type;
} }
else {
throw new RuntimeException("Variable " + name + " not declared in method"); private Type checkMethodVariableType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isParameterWitNameInMethod(name)) {
type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name);
} else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) {
type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name);
} else {
return checkFieldOrMethodOrRecursiveType(typedProgram);
} }
return type;
} }
throw new RuntimeException("Variable " + name + " not declared ");
private Type checkFieldOrMethodOrRecursiveType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isThereField(name)) {
type = typedProgram.getCurrentClass().getFieldType(name);
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = typedProgram.getCurrentClass().getMethodType(name);
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
} else {
throw new RuntimeException("Variable " + name + " not declared");
} }
return type;
} }
@Override @Override

View File

@ -5,9 +5,6 @@ import de.maishai.typedast.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -21,25 +18,25 @@ public class TypedFor implements TypedStatement {
private TypedBlock typedBlock; private TypedBlock typedBlock;
private Type type; private Type type;
public TypedFor(TypedClass clas, For unTypedFor) { public TypedFor(TypedProgram typedProgram, For unTypedFor) {
convertToTypedFor(clas, unTypedFor); convertToTypedFor(typedProgram, unTypedFor);
} }
public void convertToTypedFor(TypedClass clas, For unTypedFor) { public void convertToTypedFor(TypedProgram typedProgram, For unTypedFor) {
assign = new TypedAssignment(clas, unTypedFor.assign()); assign = new TypedAssignment(typedProgram, unTypedFor.assign());
cond = convertExpression(clas, unTypedFor.cond()); cond = convertExpression(typedProgram, unTypedFor.cond());
inc = new TypedAssignment(clas, unTypedFor.inc()); inc = new TypedAssignment(typedProgram, unTypedFor.inc());
typedBlock = new TypedBlock(clas, unTypedFor.block()); typedBlock = new TypedBlock(typedProgram, unTypedFor.block());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
assign.typeCheck(clas); assign.typeCheck(typedProgram);
if (!cond.typeCheck(clas).equals(Type.BOOL)) { if (!cond.typeCheck(typedProgram).equals(Type.BOOL)) {
throw new RuntimeException("Condition must be a boolean"); throw new RuntimeException("Condition must be a boolean");
} }
inc.typeCheck(clas); inc.typeCheck(typedProgram);
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(typedProgram);
return type; return type;
} }

View File

@ -5,11 +5,8 @@ import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -20,35 +17,27 @@ public class TypedIfElse implements TypedStatement {
private TypedBlock elseTypedBlock; private TypedBlock elseTypedBlock;
private Type type; private Type type;
public TypedIfElse(TypedClass clas, IfElse unTypedIfElse) { public TypedIfElse(TypedProgram typedProgram, IfElse unTypedIfElse) {
convertToTypedIfElse(clas, unTypedIfElse); convertToTypedIfElse(typedProgram, unTypedIfElse);
} }
public void convertToTypedIfElse(TypedClass clas, IfElse unTypedIfElse) { public void convertToTypedIfElse(TypedProgram typedProgram, IfElse unTypedIfElse) {
ifTypedBlock = new TypedBlock(clas, unTypedIfElse.ifBlock()); ifTypedBlock = new TypedBlock(typedProgram, unTypedIfElse.ifBlock());
elseTypedBlock = new TypedBlock(clas, unTypedIfElse.elseBlock()); elseTypedBlock = new TypedBlock(typedProgram, unTypedIfElse.elseBlock());
typedCon = convertExpression(clas, unTypedIfElse.cond()); typedCon = convertExpression(typedProgram, unTypedIfElse.cond());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
/*
if (typedCon.typeCheck(clas) != Type.BOOL) { if (ifTypedBlock.typeCheck(typedProgram) == elseTypedBlock.typeCheck(typedProgram)) {
throw new RuntimeException("If condition must be a boolean"); type = ifTypedBlock.typeCheck(typedProgram);
} }
if (ifTypedBlock.typeCheck(clas) != Type.VOID) { if (elseTypedBlock.typeCheck(typedProgram) == Type.VOID) {
throw new RuntimeException("If block must be of type void"); type = ifTypedBlock.typeCheck(typedProgram);
} }
*/ if (ifTypedBlock.typeCheck(typedProgram) == Type.VOID) {
//TODO: it still not catching the all cases when return is used type = elseTypedBlock.typeCheck(typedProgram);
if (ifTypedBlock.typeCheck(clas) == elseTypedBlock.typeCheck(clas)) {
type = ifTypedBlock.typeCheck(clas);
}
if (elseTypedBlock.typeCheck(clas) == Type.VOID) {
type = ifTypedBlock.typeCheck(clas);
}
if (ifTypedBlock.typeCheck(clas) == Type.VOID) {
type = elseTypedBlock.typeCheck(clas);
} }
return type; return type;

View File

@ -3,7 +3,6 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.IntLiteral; import de.maishai.ast.records.IntLiteral;
import de.maishai.typedast.MethodContext; import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@ -21,17 +20,17 @@ public class TypedIntLiteral implements TypedExpression {
private Type type; private Type type;
public TypedIntLiteral(TypedClass clas, IntLiteral unTypedIntLiteral) { public TypedIntLiteral(TypedProgram typedProgram, IntLiteral unTypedIntLiteral) {
convertToTypedIntLiteral(clas, unTypedIntLiteral); convertToTypedIntLiteral(typedProgram, unTypedIntLiteral);
} }
public void convertToTypedIntLiteral(TypedClass clas, IntLiteral unTypedIntLiteral) { public void convertToTypedIntLiteral(TypedProgram typedProgram, IntLiteral unTypedIntLiteral) {
value = unTypedIntLiteral.value(); value = unTypedIntLiteral.value();
type = Type.INT; type = Type.INT;
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
return type; return type;
} }

View File

@ -16,30 +16,30 @@ public final class TypedLocalVariable implements TypedNode {
private String name; private String name;
private Type type; private Type type;
public TypedLocalVariable(TypedClass clas, Declaration declaration) { public TypedLocalVariable(TypedProgram typedProgram, Declaration declaration) {
convertToTypedLocalVariable(clas, declaration); convertToTypedLocalVariable(typedProgram, declaration);
} }
public void convertToTypedLocalVariable(TypedClass clas, Declaration declaration) { public void convertToTypedLocalVariable(TypedProgram typedProgram, Declaration declaration) {
name = declaration.name(); name = declaration.name();
type = declaration.type(); type = declaration.type();
typeCheck(clas); typeCheck(typedProgram);
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent() && !clas.isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.getCurrentMethod().isLocalVariableInMethod(name)) { if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(name)) {
throw new RuntimeException("Variable " + name + " already declared"); throw new RuntimeException("Variable " + name + " already declared");
} }
clas.getCurrentMethod().getLocalVariables().add(this); typedProgram.getCurrentClass().getCurrentMethod().getLocalVariables().add(this);
return type; return type;
} }
if (!clas.isCurrentMethodPresent() && clas.isCurrentConstructorPresent()) { if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.getCurrentConstructor().isLocalVariableInConstructor(name)) { if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(name)) {
throw new RuntimeException("Variable " + name + " already declared"); throw new RuntimeException("Variable " + name + " already declared");
} }
clas.getCurrentConstructor().getLocalVariables().add(this); typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariables().add(this);
return type; return type;
} }
throw new RuntimeException("not found method or constructor in class"); throw new RuntimeException("not found method or constructor in class");

View File

@ -1,6 +1,5 @@
package de.maishai.typedast.typedclass; package de.maishai.typedast.typedclass;
import de.maishai.ast.records.IfElse;
import de.maishai.ast.records.Method; import de.maishai.ast.records.Method;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
@ -20,28 +19,37 @@ public class TypedMethod implements TypedNode {
private List<TypedLocalVariable> localVariables = new ArrayList<>(); private List<TypedLocalVariable> localVariables = new ArrayList<>();
private TypedBlock typedBlock; private TypedBlock typedBlock;
public TypedMethod(TypedClass clas, Method unTypedMethod) { public TypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
convertToTypedMethod(clas, unTypedMethod); convertToTypedMethod(typedProgram, unTypedMethod);
} }
public void convertToTypedMethod(TypedClass clas, Method unTypedMethod) { public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
name = unTypedMethod.methodName(); name = unTypedMethod.methodName();
returnType = unTypedMethod.type(); returnType = unTypedMethod.type();
for (var parameter : unTypedMethod.params()) { for (var parameter : unTypedMethod.params()) {
typedParameters.add(new TypedParameter(clas, parameter)); TypedParameter typedParameter = new TypedParameter(typedProgram, parameter);
checkIfParameterExists(typedParameter.getParaName());
typedParameters.add(typedParameter);
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
} }
clas.getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse( typedProgram.getCurrentClass().getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse(
method -> { method -> {
throw new RuntimeException("Method " + name + " already exists"); throw new RuntimeException("Method " + name + " already exists");
}, () -> { }, () -> {
}); });
} }
public void convertToTypedBlock(TypedClass clas, Method unTypedMethod) { public void checkIfParameterExists(String parameterName) {
typedBlock = new TypedBlock(clas, unTypedMethod.block()); if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName))) {
typeCheck(clas); throw new RuntimeException("Parameter " + parameterName + " already exists");
}
}
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
typeCheck(typedProgram);
} }
public boolean isLocalVariablePresent(String localVarName) { public boolean isLocalVariablePresent(String localVarName) {
@ -84,9 +92,9 @@ public class TypedMethod implements TypedNode {
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) { if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) {
if (typedBlock.typeCheck(clas).getKind() != returnType.getKind()) { if (typedBlock.typeCheck(typedProgram).getKind() != returnType.getKind()) {
if (hasEvenReturnsInIfElseBlocks()) { if (hasEvenReturnsInIfElseBlocks()) {
throw new RuntimeException("Method " + name + " must have even returns in if else blocks"); throw new RuntimeException("Method " + name + " must have even returns in if else blocks");
} else { } else {

View File

@ -8,10 +8,10 @@ import lombok.NoArgsConstructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
//TODO: test this after fixing error from parser
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@ -20,44 +20,66 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
private List<TypedExpression> args = new ArrayList<>(); private List<TypedExpression> args = new ArrayList<>();
private Type type; private Type type;
public TypedMethodCall(TypedClass clas, MethodCall unTypedMethodCall) { public TypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
convertToTypedMethodCall(clas, unTypedMethodCall); convertToTypedMethodCall(typedProgram, unTypedMethodCall);
} }
public void convertToTypedMethodCall(TypedClass clas, MethodCall unTypedMethodCall) { public void convertToTypedMethodCall(TypedProgram typedProgram, MethodCall unTypedMethodCall) {
recipient = new TypedFieldVarAccess(clas, unTypedMethodCall.recipient()); recipient = new TypedFieldVarAccess(typedProgram, unTypedMethodCall.recipient());
recipient.typeCheck(typedProgram);
for (Expression arg : unTypedMethodCall.args()) { for (Expression arg : unTypedMethodCall.args()) {
args.add(convertExpression(clas, arg)); args.add(convertExpression(typedProgram, arg));
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent() || clas.isCurrentConstructorPresent()) { String ownerChainName = null;
if (recipient.getRecursiveOwnerChain() != null) {
ownerChainName = recipient.getRecursiveOwnerChain().getType().getReference();
}
List<TypedMethod> methods = clas.getTypedMethods().stream() if (!typedProgram.getCurrentClass().getClassName().equals(ownerChainName) && ownerChainName != null) {
.filter(method -> method.getName().equals(recipient.getName())) Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getTypedClass(ownerChainName), recipient.getName());
if (matchingMethod.isPresent()) {
type = matchingMethod.get();
return type;
}
}
if (typedProgram.getCurrentClass().isCurrentMethodPresent() || typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getCurrentClass(), recipient.getName());
if (matchingMethod.isPresent()) {
type = matchingMethod.get();
return type;
}
}
throw new RuntimeException("Method not found");
}
public Optional<Type> findMatchingMethod(TypedClass ownerChain, String methodName) {
List<TypedMethod> methods = ownerChain.getTypedMethods().stream()
.filter(method -> method.getName().equals(methodName))
.toList(); .toList();
for (TypedMethod method : methods) { for (TypedMethod method : methods) {
if (method.getTypedParameters().size() == args.size()) { if (method.getTypedParameters().size() == args.size()) {
boolean allMatch = true; boolean allMatch = true;
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
if (!args.get(i).typeCheck(clas).equals(method.getTypedParameters().get(i).getType())) { if (!args.get(i).getType().equals(method.getTypedParameters().get(i).getType())) {
allMatch = false; allMatch = false;
break; break;
} }
} }
if (allMatch) { if (allMatch) {
type = method.getReturnType(); return Optional.of(method.getReturnType());
return type;
} }
} }
} }
}
throw new RuntimeException("Method not found");
}
return Optional.empty();
}
@Override @Override
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {

View File

@ -9,7 +9,6 @@ import org.objectweb.asm.Opcodes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -18,30 +17,35 @@ public class TypedNew implements TypedExpression, TypedStatement {
private Type type; private Type type;
private List<TypedExpression> args = new ArrayList<>(); private List<TypedExpression> args = new ArrayList<>();
public TypedNew(TypedClass clas, New unTypedNew) { public TypedNew(TypedProgram typedProgram, New unTypedNew) {
convertToTypedNew(clas, unTypedNew); convertToTypedNew(typedProgram, unTypedNew);
} }
public void convertToTypedNew(TypedClass clas, New unTypedNew) { public void convertToTypedNew(TypedProgram typedProgram, New unTypedNew) {
type = unTypedNew.type(); type = unTypedNew.type();
for (Expression arg : unTypedNew.args()) { for (Expression arg : unTypedNew.args()) {
args.add(convertExpression(clas, arg)); args.add(convertExpression(typedProgram, arg));
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
for (var constructor : clas.getTypedConstructors()) {
if (typedProgram.isTypedClassPresent(type.getReference())) {
return Type.REFERENCE(type.getReference());
}
for (var constructor : typedProgram.getCurrentClass().getTypedConstructors()) {
if (constructor.getTypedParameters().size() == args.size()) { if (constructor.getTypedParameters().size() == args.size()) {
boolean valid = true; boolean valid = true;
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
if (!constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(clas))) { if (!constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(typedProgram))) {
valid = false; valid = false;
break; break;
} }
} }
if (valid) { if (valid) {
return Type.REFERENCE(clas.getClassName()); return Type.REFERENCE(typedProgram.getCurrentClass().getClassName());
} }
} }
} }

View File

@ -6,19 +6,17 @@ import de.maishai.typedast.TypedNode;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import java.util.Map;
@AllArgsConstructor @AllArgsConstructor
@Data @Data
public class TypedParameter implements TypedNode { public class TypedParameter implements TypedNode {
private String paraName; private String paraName;
private Type type; private Type type;
public TypedParameter(TypedClass clas, Parameter unTypedParameter) { public TypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
convertToTypedParameter(clas, unTypedParameter); convertToTypedParameter(typedProgram, unTypedParameter);
} }
public void convertToTypedParameter(TypedClass clas, Parameter unTypedParameter) { public void convertToTypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
paraName = unTypedParameter.name(); paraName = unTypedParameter.name();
type = unTypedParameter.type(); type = unTypedParameter.type();
} }
@ -34,14 +32,14 @@ public class TypedParameter implements TypedNode {
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (clas.isParameterWitNameInMethod(paraName)) { if (typedProgram.getCurrentClass().isParameterWitNameInMethod(paraName)) {
throw new RuntimeException("Parameter " + paraName + " already exists"); throw new RuntimeException("Parameter " + paraName + " already exists");
} }
} else if (clas.isCurrentConstructorPresent()) { } else if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (clas.isParameterWitNameInConstructor(paraName)) { if (typedProgram.getCurrentClass().isParameterWitNameInConstructor(paraName)) {
throw new RuntimeException("Parameter " + paraName + " already exists"); throw new RuntimeException("Parameter " + paraName + " already exists");
} }
} }

View File

@ -0,0 +1,62 @@
package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Program;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
@Getter
@AllArgsConstructor
public class TypedProgram {
private List<TypedClass> typedClasses = new ArrayList<>();
private TypedClass currentClass;
public TypedProgram(Program program) {
startConversion(program);
}
public void startConversion(Program program) {
// Initialisiere die Klassen nur mit den Klassennamen und deren Typ
for (var clas : program.classes()) {
typedClasses.add(new TypedClass(clas));
}
// Konvertiere die Methoden, Konstruktoren und Felder von den jeweiligen Klassen
int k = 0;
for (var clas : program.classes()) {
enterCurrentClass(typedClasses.get(k));
typedClasses.get(k).convertMethodsAndConstructorsAndFields(this, clas);
exitCurrentClass();
k++;
}
// Konvertiere die Blöcke der Konstruktoren und Methoden von den jeweiligen Klassen
int i = 0;
for (var clas : program.classes()) {
enterCurrentClass(typedClasses.get(i));
typedClasses.get(i).covertBlocksOfConstructorsAndMethods(this, clas);
exitCurrentClass();
i++;
}
}
public TypedClass getTypedClass(String className) {
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get();
}
public boolean isTypedClassPresent(String className) {
return typedClasses.stream().anyMatch(clas -> clas.getClassName().equals(className));
}
public void enterCurrentClass(TypedClass clas) {
currentClass = clas;
}
public void exitCurrentClass() {
currentClass = null;
}
}

View File

@ -5,11 +5,8 @@ import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -18,28 +15,28 @@ public class TypedReturn implements TypedStatement {
private TypedExpression ret; private TypedExpression ret;
private Type type; private Type type;
public TypedReturn(TypedClass clas, Return unTypedReturn) { public TypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
convertToTypedReturn(clas, unTypedReturn); convertToTypedReturn(typedProgram, unTypedReturn);
} }
public void convertToTypedReturn(TypedClass clas, Return unTypedReturn) { public void convertToTypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
ret = convertExpression(clas, unTypedReturn.ret()); ret = convertExpression(typedProgram, unTypedReturn.ret());
if(ret == null){ if (ret == null) {
type = Type.VOID; type = Type.VOID;
}else{ } else {
type = ret.getType(); type = ret.getType();
} }
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent()) { if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()) { if (typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
StringBuilder exp = new StringBuilder(); StringBuilder exp = new StringBuilder();
exp.append("\nMismatched return type: "); exp.append("\nMismatched return type: ");
exp.append("\nExpected: ").append(clas.getCurrentMethod().getReturnType().getKind()); exp.append("\nExpected: ").append(typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind());
exp.append("\nActual: ").append(this.type.getKind()); exp.append("\nActual: ").append(this.type.getKind());
exp.append("\nMethod name: ").append(clas.getCurrentMethod().getName()); exp.append("\nMethod name: ").append(typedProgram.getCurrentClass().getCurrentMethod().getName());
throw new RuntimeException(exp.toString()); throw new RuntimeException(exp.toString());
} }
} }

View File

@ -6,11 +6,8 @@ import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data @Data
@ -19,28 +16,27 @@ public class TypedUnary implements TypedExpression {
private TypedExpression right; private TypedExpression right;
private Type type; private Type type;
public TypedUnary(TypedClass clas, Unary unTypedUnary) { public TypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
convertToTypedUnary(clas, unTypedUnary); convertToTypedUnary(typedProgram, unTypedUnary);
} }
public void convertToTypedUnary(TypedClass clas, Unary unTypedUnary) { public void convertToTypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
op = unTypedUnary.op(); op = unTypedUnary.op();
right = convertExpression(clas, unTypedUnary.right()); right = convertExpression(typedProgram, unTypedUnary.right());
type = right.getType();
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (op == UnaryOperator.NOT) { if (op == UnaryOperator.NOT) {
if (right.typeCheck(clas) != Type.BOOL) { if (right.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("Not operator must be applied to boolean"); throw new RuntimeException("Not operator must be applied to boolean");
} }
return Type.BOOL; return Type.BOOL;
} }
if (op == UnaryOperator.SUB) { if (op == UnaryOperator.SUB) {
if (right.typeCheck(clas) != Type.INT) { if (right.typeCheck(typedProgram) != Type.INT) {
throw new RuntimeException("Minus operator must be applied to int"); throw new RuntimeException("Minus operator must be applied to int");
} }
return Type.INT; return Type.INT;
@ -51,11 +47,11 @@ public class TypedUnary implements TypedExpression {
@Override @Override
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
right.codeGen(ctx); right.codeGen(ctx);
if(op == UnaryOperator.NOT){ if (op == UnaryOperator.NOT) {
ctx.getMv().visitInsn(Opcodes.ICONST_1); ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitInsn(Opcodes.IXOR); ctx.getMv().visitInsn(Opcodes.IXOR);
} }
if(op == UnaryOperator.SUB){ if (op == UnaryOperator.SUB) {
ctx.getMv().visitInsn(Opcodes.INEG); ctx.getMv().visitInsn(Opcodes.INEG);
} }
} }

View File

@ -3,9 +3,6 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.typedast.*; import de.maishai.typedast.*;
import lombok.Data; import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -15,21 +12,21 @@ public class TypedWhile implements TypedStatement {
private TypedBlock typedBlock; private TypedBlock typedBlock;
private Type type; private Type type;
public TypedWhile(TypedClass clas, While unTypedWhile) { public TypedWhile(TypedProgram typedProgram, While unTypedWhile) {
convertToTypedWhile(clas, unTypedWhile); convertToTypedWhile(typedProgram, unTypedWhile);
} }
public void convertToTypedWhile(TypedClass clas, While unTypedWhile) { public void convertToTypedWhile(TypedProgram typedProgram, While unTypedWhile) {
cond = convertExpression(clas, unTypedWhile.cond()); cond = convertExpression(typedProgram, unTypedWhile.cond());
typedBlock = new TypedBlock(clas, unTypedWhile.block()); typedBlock = new TypedBlock(typedProgram, unTypedWhile.block());
} }
@Override @Override
public Type typeCheck(TypedClass clas) { public Type typeCheck(TypedProgram typedProgram) {
if (cond.typeCheck(clas) != Type.BOOL) { if (cond.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("While condition must be a boolean"); throw new RuntimeException("While condition must be a boolean");
} }
type = typedBlock.typeCheck(clas); type = typedBlock.typeCheck(typedProgram);
return type; return type;
} }

View File

@ -20,7 +20,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithConstructor { public class AbstractSyntax_ClassWithConstructor {
public static Class get() { public static Program get() {
List<Declaration> declarations = List.of( List<Declaration> declarations = List.of(
new Declaration( new Declaration(
"x", "x",
@ -29,11 +29,15 @@ public class AbstractSyntax_ClassWithConstructor {
); );
List<Method> methods = List.of(); List<Method> methods = List.of();
List<Constructor> constructors = getConstructors(); List<Constructor> constructors = getConstructors();
return new Class( return new Program(
List.of(
new Class(
"ClassWithConstructor", "ClassWithConstructor",
declarations, declarations,
methods, methods,
constructors constructors
)
)
); );
} }

View File

@ -26,7 +26,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithConstructorAndMethodCall { public class AbstractSyntax_ClassWithConstructorAndMethodCall {
public static Class get() { public static Program get() {
List<Declaration> declarationList = List.of( List<Declaration> declarationList = List.of(
new Declaration( new Declaration(
"x", "x",
@ -35,11 +35,15 @@ public class AbstractSyntax_ClassWithConstructorAndMethodCall {
); );
List<Method> methodList = getMethods(); List<Method> methodList = getMethods();
List<Constructor> constructorList = getConstructors(); List<Constructor> constructorList = getConstructors();
return new Class( return new Program(
List.of(
new Class(
"ClassWithConstructorAndMethodCall", "ClassWithConstructorAndMethodCall",
declarationList, declarationList,
methodList, methodList,
constructorList constructorList
)
)
); );
} }
@ -61,7 +65,7 @@ public class AbstractSyntax_ClassWithConstructorAndMethodCall {
new While( new While(
new MethodCall( new MethodCall(
new FieldVarAccess( new FieldVarAccess(
true, false,
null, null,
"methodCall"), "methodCall"),
List.of() List.of()

View File

@ -21,7 +21,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithConstructorWithCodeInComments { public class AbstractSyntax_ClassWithConstructorWithCodeInComments {
public static Class get() { public static Program get() {
List<Declaration> declarations = List.of( List<Declaration> declarations = List.of(
new Declaration( new Declaration(
"x", "x",
@ -30,11 +30,15 @@ public class AbstractSyntax_ClassWithConstructorWithCodeInComments {
); );
List<Method> methods = List.of(); List<Method> methods = List.of();
List<Constructor> constructors = getConstructors(); List<Constructor> constructors = getConstructors();
return new Class( return new Program(
List.of(
new Class(
"ClassWithConstructorWithCodeInComments", "ClassWithConstructorWithCodeInComments",
declarations, declarations,
methods, methods,
constructors constructors
)
)
); );
} }

View File

@ -13,6 +13,7 @@
// } // }
// } // }
//} //}
import de.maishai.ast.Operator; import de.maishai.ast.Operator;
import de.maishai.ast.records.*; import de.maishai.ast.records.*;
import de.maishai.ast.records.Class; import de.maishai.ast.records.Class;
@ -21,7 +22,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithConstructorWithParameters { public class AbstractSyntax_ClassWithConstructorWithParameters {
public static Class get() { public static Program get() {
List<Declaration> declarations = List.of( List<Declaration> declarations = List.of(
new Declaration( new Declaration(
"x", "x",
@ -29,11 +30,15 @@ public class AbstractSyntax_ClassWithConstructorWithParameters {
) )
); );
List<Constructor> constructors = getConstructors(); List<Constructor> constructors = getConstructors();
return new Class( return new Program(
List.of(
new Class(
"ClassWithConstructorWithParameters", "ClassWithConstructorWithParameters",
declarations, declarations,
List.of(), List.of(),
constructors constructors
)
)
); );
} }

View File

@ -9,7 +9,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithField { public class AbstractSyntax_ClassWithField {
public static Class get() { public static Program get() {
List<Declaration> declarations = List.of( List<Declaration> declarations = List.of(
new Declaration( new Declaration(
"x", "x",
@ -28,11 +28,15 @@ public class AbstractSyntax_ClassWithField {
) )
) )
); );
return new Class( return new Program(
List.of(
new Class(
"ClassWithField", "ClassWithField",
declarations, declarations,
methods, methods,
constructors constructors
)
)
); );
} }
} }

View File

@ -11,9 +11,11 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithMethod { public class AbstractSyntax_ClassWithMethod {
public static Class get() { public static Program get() {
List<Method> methods = getMethods(); List<Method> methods = getMethods();
return new Class( return new Program(
List.of(
new Class(
"ClassWithMethod", "ClassWithMethod",
List.of(), List.of(),
methods, methods,
@ -27,6 +29,8 @@ public class AbstractSyntax_ClassWithMethod {
) )
) )
) )
)
)
); );
} }

View File

@ -18,7 +18,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
class AbstractSyntax_ClassWithMethodAndField { class AbstractSyntax_ClassWithMethodAndField {
public static Class get() { public static Program get() {
List<Declaration> declarations = List.of( List<Declaration> declarations = List.of(
new Declaration( new Declaration(
"c", "c",
@ -27,11 +27,15 @@ class AbstractSyntax_ClassWithMethodAndField {
); );
List<Method> methods = getMethods(); List<Method> methods = getMethods();
List<Constructor> constructors = getConstructors(); List<Constructor> constructors = getConstructors();
return new Class( return new Program(
List.of(
new Class(
"ClassWithMethodAndField", "ClassWithMethodAndField",
declarations, declarations,
methods, methods,
constructors constructors
)
)
); );
} }

View File

@ -26,7 +26,7 @@ import de.maishai.typedast.Type;
import java.util.List; import java.util.List;
public class AbstractSyntax_ClassWithMultipleMethods { public class AbstractSyntax_ClassWithMultipleMethods {
public static Class get() { public static Program get() {
List<Declaration> declarations = List.of( List<Declaration> declarations = List.of(
new Declaration( new Declaration(
"instance", "instance",
@ -35,11 +35,14 @@ public class AbstractSyntax_ClassWithMultipleMethods {
); );
List<Method> methods = getMethods(); List<Method> methods = getMethods();
List<Constructor> constructors = List.of(); List<Constructor> constructors = List.of();
return new Class( return new Program(
List.of(new Class(
"ClassWithMoreComplexMethodAndMain", "ClassWithMoreComplexMethodAndMain",
declarations, declarations,
methods, methods,
constructors constructors
)
)
); );
} }

View File

@ -0,0 +1,902 @@
//public class ComplexClass {
//
// int x;
// int y;
// ComplexClass b;
// ComplexClass c;
//
// public ComplexClass() {
// this.y = 10;
// this.x = 2;
// int i;
// for (i = 0; i < (this.y + 1); i = i + 1) {
// int j;
// for (j = 0; j < this.y; j += 1) {
// this.x = this.x * this.x;
// if (this.x == 100) {
// break;
// }
// }
// }
// this.y = 2;
// do {
// this.y = this.y + 1;
// } while (this.y < 10);
//
// int k;
// k = 0;
// for (k = 0; k < 10; k = k + 1) {
// if (k == 5) {
// return this;
// }
// }
//
// }
//
// public ComplexClass(int x) {
// this.b = new ComplexClass();
// this.c = new ComplexClass();
// this.x = x;
// this.b.x = 7;
// this.b.y = 13;
// this.c.x = this.b.getX() * this.b.y * this.b.getX('g');
// this.c.y = 25;
// }
//
// public ComplexClass(int x, int y) {
// this.x = x;
// this.y = y;
// }
//
// public ComplexClass initComplexClass(int x) {
// int a;
// a = 10;
// this.b = new ComplexClass(x);
// this.b.x = 10 + a;
// this.b.y = 20;
// this.b.c.x = 20 + a;
// if (methodCall()) {
// this.b.getC().b.y = this.b.x;
// }
// return this.b;
// }
//
// public ComplexClass init(int x, int y) {
// return new ComplexClass(x, y);
// }
//
// public ComplexClass(int x, int y, char z) {
// this.x = x;
// this.y = y;
// }
//
// public int getX(char z) {
// return this.x;
// }
//
// public ComplexClass getC() {
// return this.c;
// }
//
// public int getX() {
// return this.x;
// }
//
// public boolean methodCall() {
// return false;
// }
//
//}
import de.maishai.ast.Operator;
import de.maishai.ast.records.*;
import de.maishai.ast.records.Class;
import de.maishai.typedast.Type;
import java.util.List;
@SuppressWarnings("DuplicateExpressions")
public class AbstractSyntax_ComplexClass {
public static Program get() {
List<Declaration> declarationList = List.of(
new Declaration(
"x",
Type.INT
),
new Declaration(
"y",
Type.INT
),
new Declaration(
"b",
Type.REFERENCE("ComplexClass")
),
new Declaration(
"c",
Type.REFERENCE("ComplexClass")
)
);
List<Method> methodList = getMethods();
List<Constructor> constructorList = getConstructors();
return new Program(
List.of(
new Class(
"ComplexClass",
declarationList,
methodList,
constructorList
)
)
);
}
private static List<Constructor> getConstructors() {
return List.of(
getConstructor1(),
getConstructor2(),
getConstructor3(),
getConstructor4()
);
}
private static Constructor getConstructor1() {
Block block = new Block(
List.of(
new Declaration(
"i",
Type.INT
),
new Declaration(
"k",
Type.INT
)
),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new IntLiteral(10)
),
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new IntLiteral(2)
),
new For(
new Assignment(
new FieldVarAccess(
false,
null,
"i"),
new IntLiteral(0)
),
new Binary(
new FieldVarAccess(
false,
null,
"i"),
Operator.LT,
new Binary(
new FieldVarAccess(
true,
null,
"y"),
Operator.ADD,
new IntLiteral(1)
)
),
new Assignment(
new FieldVarAccess(
false,
null,
"i"),
new Binary(
new FieldVarAccess(
false,
null,
"i"),
Operator.ADD,
new IntLiteral(1)
)
),
new Block(
List.of(
new Declaration(
"j",
Type.INT
)
),
List.of(
new For(
new Assignment(
new FieldVarAccess(
false,
null,
"j"),
new IntLiteral(0)
),
new Binary(
new FieldVarAccess(
false,
null,
"j"),
Operator.LT,
new FieldVarAccess(
true,
null,
"y"
)
),
new Assignment(
new FieldVarAccess(
false,
null,
"j"),
new Binary(
new FieldVarAccess(
false,
null,
"j"),
Operator.ADD,
new IntLiteral(1)
)
),
new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new Binary(
new FieldVarAccess(
true,
null,
"x"),
Operator.MUL,
new FieldVarAccess(
true,
null,
"x"
)
)
),
new IfElse(
new Binary(
new FieldVarAccess(
true,
null,
"x"),
Operator.EQ,
new IntLiteral(100)
),
new Block(
List.of(),
List.of(
new Break()
)
),
null
)
)
)
)
)
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new IntLiteral(2)
),
new DoWhile(
new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new Binary(
new FieldVarAccess(
true,
null,
"y"),
Operator.ADD,
new IntLiteral(1)
)
)
)
),
new Binary(
new FieldVarAccess(
true,
null,
"y"),
Operator.LT,
new IntLiteral(10)
)
),
new Assignment(
new FieldVarAccess(
false,
null,
"k"),
new IntLiteral(0)
),
new For(
new Assignment(
new FieldVarAccess(
false,
null,
"k"),
new IntLiteral(0)
),
new Binary(
new FieldVarAccess(
false,
null,
"k"),
Operator.LT,
new IntLiteral(10)
),
new Assignment(
new FieldVarAccess(
false,
null,
"k"),
new Binary(
new FieldVarAccess(
false,
null,
"k"),
Operator.ADD,
new IntLiteral(1)
)
),
new Block(
List.of(),
List.of(
new IfElse(
new Binary(
new FieldVarAccess(
false,
null,
"k"),
Operator.EQ,
new IntLiteral(5)
),
new Block(
List.of(),
List.of(
new Return(
new This()
)
)
),
null
)
)
)
)
)
);
return new Constructor(
"ComplexClass",
List.of(),
block
);
}
private static Constructor getConstructor2() {
Block block = new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"b"),
new New(
Type.REFERENCE("ComplexClass"),
List.of()
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"c"),
new New(
Type.REFERENCE("ComplexClass"),
List.of()
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new FieldVarAccess(
false,
null,
"x"
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"x"),
new IntLiteral(7)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"y"),
new IntLiteral(13)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"c"),
"x"),
new Binary(
new Binary(
new MethodCall(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"getX"
),
List.of()
),
Operator.MUL,
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"y"
)
),
Operator.MUL,
new MethodCall(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"getX"
),
List.of(
new CharLiteral('g')
)
)
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"c"),
"y"),
new IntLiteral(25)
)
)
);
return new Constructor(
"ComplexClass",
List.of(
new Parameter(
"x",
Type.INT
)
),
block
);
}
private static Constructor getConstructor3() {
Block block = new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new FieldVarAccess(
false,
null,
"x"
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new FieldVarAccess(
false,
null,
"y"
)
)
)
);
return new Constructor(
"ComplexClass",
List.of(
new Parameter(
"x",
Type.INT
),
new Parameter(
"y",
Type.INT
)
),
block
);
}
private static Constructor getConstructor4() {
Block block = new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
null,
"x"),
new FieldVarAccess(
false,
null,
"x"
)
),
new Assignment(
new FieldVarAccess(
true,
null,
"y"),
new FieldVarAccess(
false,
null,
"y"
)
)
)
);
return new Constructor(
"ComplexClass",
List.of(
new Parameter(
"x",
Type.INT
),
new Parameter(
"y",
Type.INT
),
new Parameter(
"z",
Type.CHAR
)
),
block
);
}
private static List<Method> getMethods() {
return List.of(
getMethod1(),
getMethod2(),
getMethod3(),
getMethod4(),
getMethod5(),
getMethod6()
);
}
private static Method getMethod1() {
Block block = new Block(
List.of(
new Declaration(
"a",
Type.INT
)
),
List.of(
new Assignment(
new FieldVarAccess(
false,
null,
"a"),
new IntLiteral(10)
),
new Assignment(
new FieldVarAccess(
true,
null,
"b"),
new New(
Type.REFERENCE("ComplexClass"),
List.of(
new FieldVarAccess(
false,
null,
"x"
)
)
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"x"),
new Binary(
new IntLiteral(10),
Operator.ADD,
new FieldVarAccess(
false,
null,
"a"
)
)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"),
"y"),
new IntLiteral(20)
),
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
new FieldVarAccess(
false,
null,
"b"),
"c"),
"x"),
new Binary(
new IntLiteral(20),
Operator.ADD,
new FieldVarAccess(
false,
null,
"a"
)
)
),
new IfElse(
new MethodCall(
new FieldVarAccess(
false,
null,
"methodCall"),
List.of()
),
new Block(
List.of(),
List.of(
new Assignment(
new FieldVarAccess(
true,
new FieldVarAccess(
false,
new MethodCall(
new FieldVarAccess(
false,
new FieldVarAccess(
false,
null,
"b"
),
"getC"
),
List.of()
),
"b"),
"y"),
new FieldVarAccess(
true,
new FieldVarAccess(
false,
null,
"b"
),
"x"
)
)
)
),
null
),
new Return(
new FieldVarAccess(
true,
null,
"b"
)
)
)
);
return new Method(
Type.REFERENCE("ComplexClass"),
"initComplexClass",
List.of(
new Parameter(
"x",
Type.INT
)
),
block
);
}
private static Method getMethod2() {
Block block = new Block(
List.of(),
List.of(
new Return(
new New(
Type.REFERENCE("ComplexClass"),
List.of(
new FieldVarAccess(
false,
null,
"x"
),
new FieldVarAccess(
false,
null,
"y"
)
)
)
)
)
);
return new Method(
Type.REFERENCE("ComplexClass"),
"init",
List.of(
new Parameter(
"x",
Type.INT
),
new Parameter(
"y",
Type.INT
)
),
block
);
}
private static Method getMethod3() {
Block block = new Block(
List.of(),
List.of(
new Return(
new FieldVarAccess(
true,
null,
"x"
)
)
)
);
return new Method(
Type.INT,
"getX",
List.of(
new Parameter(
"z",
Type.CHAR
)
),
block
);
}
private static Method getMethod4() {
Block block = new Block(
List.of(),
List.of(
new Return(
new FieldVarAccess(
true,
null,
"c"
)
)
)
);
return new Method(
Type.REFERENCE("ComplexClass"),
"getC",
List.of(),
block
);
}
private static Method getMethod5() {
Block block = new Block(
List.of(),
List.of(
new Return(
new FieldVarAccess(
true,
null,
"x"
)
)
)
);
return new Method(
Type.INT,
"getX",
List.of(),
block
);
}
private static Method getMethod6() {
Block block = new Block(
List.of(),
List.of(
new Return(
new BoolLiteral(false)
)
)
);
return new Method(
Type.BOOL,
"methodCall",
List.of(),
block
);
}
}

View File

@ -4,12 +4,15 @@
import de.maishai.ast.records.Block; import de.maishai.ast.records.Block;
import de.maishai.ast.records.Class; import de.maishai.ast.records.Class;
import de.maishai.ast.records.Constructor; import de.maishai.ast.records.Constructor;
import de.maishai.ast.records.Program;
import java.util.List; import java.util.List;
public class AbstractSyntax_PublicClass { public class AbstractSyntax_PublicClass {
public static Class get() { public static Program get() {
return new Class( return new Program(
List.of(
new Class(
"PublicClass", "PublicClass",
List.of(), List.of(),
List.of(), List.of(),
@ -23,6 +26,8 @@ public class AbstractSyntax_PublicClass {
) )
) )
) )
)
)
); );
} }

View File

@ -0,0 +1,89 @@
public class ComplexClass {
int x;
int y;
ComplexClass b;
ComplexClass c;
public ComplexClass() {
this.y = 10;
this.x = 2;
int i;
for (i = 0; i < (this.y + 1); i = i + 1) {
int j;
for (j = 0; j < this.y; j += 1) {
this.x = this.x * this.x;
if (this.x == 100) {
break;
}
}
}
this.y = 2;
do {
this.y = this.y + 1;
} while (this.y < 10);
int k;
k = 0;
for (k = 0; k < 10; k = k + 1) {
if (k == 5) {
return this;
}
}
}
public ComplexClass(int x) {
this.b = new ComplexClass();
this.c = new ComplexClass();
this.x = x;
this.b.x = 7;
this.b.y = 13;
this.c.x = this.b.getX() * this.b.y * this.b.getX('g');
this.c.y = 25;
}
public ComplexClass(int x, int y) {
this.x = x;
this.y = y;
}
public ComplexClass initComplexClass(int x) {
int a;
a = 10;
this.b = new ComplexClass(x);
this.b.x = 10 + a;
this.b.y = 20;
this.b.c.x = 20 + a;
if (methodCall()) {
this.b.getC().b.y = this.b.x;
}
return this.b;
}
public ComplexClass init(int x, int y) {
return new ComplexClass(x, y);
}
public ComplexClass(int x, int y, char z) {
this.x = x;
this.y = y;
}
public int getX(char z) {
return this.x;
}
public ComplexClass getC() {
return this.c;
}
public int getX() {
return this.x;
}
public boolean methodCall() {
return false;
}
}

View File

@ -14,140 +14,218 @@
import de.maishai.ast.Operator; import de.maishai.ast.Operator;
import de.maishai.typedast.Type; import de.maishai.typedast.Type;
import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.typedclass.*; import de.maishai.typedast.typedclass.*;
import java.util.List; import java.util.List;
public class TypedAbstractSyntax_ClassWithConstructor { public class TypedAbstractSyntax_ClassWithConstructor {
// public static TypedClass get() { public static TypedProgram get() {
// TypedClass typedClass = new TypedClass(); return new TypedProgram(
// typedClass.setIsPublic(true); List.of(
// typedClass.setTypedId(new TypedId("ClassWithConstructor")); new TypedClass(
// "ClassWithConstructor",
// TypedField typedField = new TypedField(); List.of(
// typedField.setTypedId(new TypedId("x")); new TypedDeclaration(
// typedField.setType(Type.INT); "x",
// Type.INT
// typedClass.setTypedFields(List.of(typedField)); )
// typedClass.setTypedMethods(List.of()); ),
// typedClass.setTypedMainMethod(null); List.of(),
// typedClass.setTypedConstructors(getConstructors()); getConstructors(),
// return typedClass; null,
// } null,
// Type.REFERENCE("ClassWithField")
// private static List<TypedConstructor> getConstructors() { )
// return List.of(getConstructor1()); ),
// } null
// );
// private static TypedConstructor getConstructor1() { }
// TypedConstructor typedConstructor = new TypedConstructor();
// typedConstructor.setIsPublic(true); private static List<TypedConstructor> getConstructors() {
// typedConstructor.setTypedId(new TypedId("ClassWithConstructor")); return List.of(getTypedConstructor1());
// typedConstructor.setTypedParameters(List.of()); }
//
// TypedBlock typedBlock = new TypedBlock(); private static TypedConstructor getTypedConstructor1() {
// List<TypedParameter> typedParameters = List.of();
// TypedLocalVariable typedLocalVariable = new TypedLocalVariable();
// typedLocalVariable.setTypedId(new TypedId("i")); List<TypedLocalVariable> typedLocalVariables = List.of(
// typedLocalVariable.setType(Type.INT); new TypedLocalVariable(
// "i",
// typedBlock.setVars(List.of(typedLocalVariable)); Type.INT
// )
// TypedAssignment typedAssignment = new TypedAssignment(); );
// typedAssignment.setLoc(new TypedId("x")); List<TypedStatement> typedStatementList =
//// typedAssignment.setAssignSign(AssignSign.ASSIGN); List.of(
// typedAssignment.setValue(new TypedIntLiteral(10)); new TypedAssignment(
// new TypedIntLiteral(
// TypedFor typedFor = new TypedFor(); 10,
// Type.INT),
// TypedAssignment typedAssignmentFor = new TypedAssignment(); new TypedFieldVarAccess(
// typedAssignmentFor.setLoc(new TypedId("i")); true,
//// typedAssignmentFor.setAssignSign(AssignSign.ASSIGN); null,
// typedAssignmentFor.setValue(new TypedIntLiteral(0)); "x",
// Type.INT
//// typedFor.setAssign(typedAssignmentFor); ),
// Type.INT
// TypedBinary typedBinaryFor = new TypedBinary(); ),
// typedBinaryFor.setLeft(new TypedId("i")); new TypedFor(
// typedBinaryFor.setOp(Operator.LT); new TypedAssignment(
// typedBinaryFor.setRight(new TypedIntLiteral(6)); new TypedIntLiteral(
// 0,
// typedFor.setCond(typedBinaryFor); Type.INT),
// new TypedFieldVarAccess(
// TypedBinary typedBinaryForIncr = new TypedBinary(); false,
// typedBinaryForIncr.setLeft(new TypedId("i")); null,
// typedBinaryForIncr.setOp(Operator.ADD); "i",
// typedBinaryForIncr.setRight(new TypedIntLiteral(1)); Type.INT
// ),
// TypedAssignment typedAssignmentForIncr = new TypedAssignment(); Type.INT
// typedAssignmentForIncr.setLoc(new TypedId("i")); ),
//// typedAssignmentForIncr.setAssignSign(AssignSign.ASSIGN); new TypedBinary(
// typedAssignmentForIncr.setValue(typedBinaryForIncr); new TypedFieldVarAccess(
// false,
//// typedFor.setInc(typedAssignmentForIncr); null,
// "i",
// TypedBlock typedBlockFor = new TypedBlock(); Type.INT
// ),
// TypedLocalVariable typedLocalVariableFor = new TypedLocalVariable(); Operator.LT,
// typedLocalVariableFor.setTypedId(new TypedId("j")); new TypedIntLiteral(
// typedLocalVariableFor.setType(Type.INT); 6,
// Type.INT
// typedBlockFor.setVars(List.of(typedLocalVariableFor)); ),
// Type.BOOL
// TypedFor typedInnerFor = new TypedFor(); ),
// new TypedAssignment(
// TypedAssignment typedAssignmentInnerFor = new TypedAssignment(); new TypedBinary(
// typedAssignmentInnerFor.setLoc(new TypedId("j")); new TypedFieldVarAccess(
//// typedAssignmentInnerFor.setAssignSign(AssignSign.ASSIGN); false,
// typedAssignmentInnerFor.setValue(new TypedIntLiteral(0)); null,
// "i",
//// typedInnerFor.setAssign(typedAssignmentInnerFor); Type.INT),
// Operator.ADD,
// TypedBinary typedBinaryInnerFor = new TypedBinary(); new TypedIntLiteral(
// typedBinaryInnerFor.setLeft(new TypedId("j")); 1,
// typedBinaryInnerFor.setOp(Operator.LT); Type.INT
// typedBinaryInnerFor.setRight(new TypedId("x")); ),
// Type.INT
// typedInnerFor.setCond(typedBinaryInnerFor); ),
// new TypedFieldVarAccess(
// TypedAssignment typedAssignmentInnerForIncr = new TypedAssignment(); false,
// typedAssignmentInnerForIncr.setLoc(new TypedId("j")); null,
//// typedAssignmentInnerForIncr.setAssignSign(AssignSign.ADD_ASSIGN); "i",
// typedAssignmentInnerForIncr.setValue(new TypedIntLiteral(1)); Type.INT
// ),
//// typedInnerFor.setInc(typedAssignmentInnerForIncr); Type.INT
// ),
// TypedBlock typedBlockInnerFor = new TypedBlock(); new TypedBlock(
// typedBlockInnerFor.setVars(List.of()); List.of(
// new TypedLocalVariable(
// TypedAssignment typedAssignmentInnerForBlock = new TypedAssignment(); "j",
// typedAssignmentInnerForBlock.setLoc(new TypedId("x")); Type.INT
//// typedAssignmentInnerForBlock.setAssignSign(AssignSign.ASSIGN); )
// ),
// TypedBinary typedBinaryInnerForBlock = new TypedBinary(); List.of(
// typedBinaryInnerForBlock.setLeft(new TypedId("x")); new TypedFor(
// typedBinaryInnerForBlock.setOp(Operator.MUL); new TypedAssignment(
// typedBinaryInnerForBlock.setRight(new TypedId("x")); new TypedIntLiteral(
// 0,
// typedAssignmentInnerForBlock.setValue(typedBinaryInnerForBlock); Type.INT),
// new TypedFieldVarAccess(
// typedBlockInnerFor.setStmts(List.of(typedAssignmentInnerForBlock)); false,
// null,
// typedInnerFor.setTypedBlock(typedBlockInnerFor); "j",
// Type.INT
// typedBlockFor.setStmts(List.of(typedInnerFor)); ),
// Type.INT
// typedFor.setTypedBlock(typedBlockFor); ),
// new TypedBinary(
// typedBlock.setStmts( new TypedFieldVarAccess(
// List.of( false,
// typedAssignment, null,
// typedFor "j",
// ) Type.INT
// ); ),
// Operator.LT,
// typedConstructor.setTypedBlock(typedBlock); new TypedFieldVarAccess(
// true,
// return typedConstructor; null,
// } "x",
Type.INT
),
Type.BOOL
),
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT),
Operator.ADD,
new TypedIntLiteral(
1,
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT
),
Type.INT
),
new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT),
Operator.MUL,
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT),
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
)
),
Type.INT
),
Type.INT
)
),
Type.INT
),
Type.INT
)
);
TypedBlock typedBlock = new TypedBlock(
typedLocalVariables,
typedStatementList,
Type.INT
);
return new TypedConstructor(
"ClassWithConstructor",
typedParameters,
typedBlock,
Type.VOID,
List.of()
);
}
} }

View File

@ -9,18 +9,37 @@ import de.maishai.typedast.typedclass.*;
import java.util.List; import java.util.List;
public class TypedAbstractSyntax_ClassWithField { public class TypedAbstractSyntax_ClassWithField {
// public static TypedClass get() { public static TypedProgram get() {
// TypedClass typedClass = new TypedClass(); return new TypedProgram(
// typedClass.setIsPublic(true); List.of(
// typedClass.setTypedId(new TypedId("ClassWithField")); new TypedClass(
// typedClass.setTypedFields( "ClassWithField",
// List.of( List.of(
// new TypedField(new TypedId("x"), Type.INT) new TypedDeclaration(
// ) "x",
// ); Type.INT
// typedClass.setTypedMethods(List.of()); )
// typedClass.setTypedMainMethod(null); ),
// typedClass.setTypedConstructors(List.of()); List.of(),
// return typedClass; List.of(
// } new TypedConstructor(
"ClassWithField",
List.of(),
new TypedBlock(
List.of(),
List.of(),
Type.VOID
),
Type.VOID,
List.of()
)
),
null,
null,
Type.REFERENCE("ClassWithField")
)
),
null
);
}
} }

View File

@ -1,19 +1,38 @@
//public class PublicClass { //public class PublicClass {
//} //}
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.*; import de.maishai.typedast.typedclass.*;
import java.util.List; import java.util.List;
public class TypedAbstractSyntax_PublicClass { public class TypedAbstractSyntax_PublicClass {
// public static TypedClass get() { public static TypedProgram get() {
// TypedClass typedClass = new TypedClass(); return new TypedProgram(
// typedClass.setIsPublic(true); List.of(
// typedClass.setTypedId(new TypedId("PublicClass")); new TypedClass(
// typedClass.setTypedFields(List.of()); "PublicClass",
// typedClass.setTypedMethods(List.of()); List.of(),
// typedClass.setTypedMainMethod(null); List.of(),
// typedClass.setTypedConstructors(List.of()); List.of(
// return typedClass; new TypedConstructor(
// } "PublicClass",
List.of(),
new TypedBlock(
List.of(),
List.of(),
Type.VOID
),
Type.VOID,
List.of()
)
),
null,
null,
Type.REFERENCE("PublicClass")
)
),
null
);
}
} }

View File

@ -0,0 +1,16 @@
import de.maishai.Compiler;
import de.maishai.ast.records.Program;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CodegeneratorTests {
// @Test
// public void testPublicClass() {
// byte[] resultBytecode = Compiler.generateByteCodeArrayFromTypedAst();
// assertEquals(AbstractSyntax_PublicClass.get(), resultBytecode);
// }
}

View File

@ -1,3 +1,7 @@
public class E2ETests { public class E2ETests {
char ZZ;
public E2ETests() {
this.ZZ = 'z';
}
} }

View File

@ -1,56 +1,64 @@
import de.maishai.Compiler; import de.maishai.Compiler;
import de.maishai.ast.records.Class; import de.maishai.ast.records.Program;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
public class ScannerParserTests { public class ScannerParserTests {
@Test @Test
public void testPublicClass() { public void testPublicClass() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/PublicClass.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/PublicClass.java"));
assertEquals(AbstractSyntax_PublicClass.get(), resultAst); assertEquals(AbstractSyntax_PublicClass.get(), resultAst);
} }
@Test @Test
public void testClassWithField() { public void testClassWithField() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithField.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithField.java"));
assertEquals(AbstractSyntax_ClassWithField.get(), resultAst); assertEquals(AbstractSyntax_ClassWithField.get(), resultAst);
} }
@Test @Test
public void testClassWithConstructor() { public void testClassWithConstructor() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructor.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructor.java"));
assertEquals(AbstractSyntax_ClassWithConstructor.get(), resultAst); assertEquals(AbstractSyntax_ClassWithConstructor.get(), resultAst);
} }
@Test @Test
public void testClassWithMethod() { public void testClassWithMethod() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithMethod.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithMethod.java"));
assertEquals(AbstractSyntax_ClassWithMethod.get(), resultAst); assertEquals(AbstractSyntax_ClassWithMethod.get(), resultAst);
} }
@Test @Test
public void testClassWithConstructorWithCodeInComments() { public void testClassWithConstructorWithCodeInComments() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructorWithCodeInComments.java"));
assertEquals(AbstractSyntax_ClassWithConstructorWithCodeInComments.get(), resultAst); assertEquals(AbstractSyntax_ClassWithConstructorWithCodeInComments.get(), resultAst);
} }
@Test @Test
public void testClassWithConstructorWithParameters() { public void testClassWithConstructorWithParameters() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorWithParameters.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructorWithParameters.java"));
assertEquals(AbstractSyntax_ClassWithConstructorWithParameters.get(), resultAst); assertEquals(AbstractSyntax_ClassWithConstructorWithParameters.get(), resultAst);
} }
@Test @Test
public void testClassWithMethodAndField() { public void testClassWithMethodAndField() {
Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithMethodAndField.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithMethodAndField.java"));
assertEquals(AbstractSyntax_ClassWithMethodAndField.get(), resultAst); assertEquals(AbstractSyntax_ClassWithMethodAndField.get(), resultAst);
} }
// @Test @Test
// public void testClassWithConstructorAndMethodCall() { public void testClassWithConstructorAndMethodCall() {
// Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java"); Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java"));
// assertEquals(AbstractSyntax_ClassWithConstructorAndMethodCall.get(), resultAst); assertEquals(AbstractSyntax_ClassWithConstructorAndMethodCall.get(), resultAst);
// } }
@Test
public void testComplexClass() {
Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ComplexClass.java"));
assertEquals(AbstractSyntax_ComplexClass.get(), resultAst);
}
} }

View File

@ -0,0 +1,26 @@
import de.maishai.Compiler;
import de.maishai.typedast.typedclass.TypedProgram;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TypingTests {
@Test
public void testPublicClass() {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_PublicClass.get());
assertEquals(TypedAbstractSyntax_PublicClass.get(), resultTypedAst);
}
@Test
public void testClassWithField() {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_ClassWithField.get());
assertEquals(TypedAbstractSyntax_ClassWithField.get(), resultTypedAst);
}
@Test
public void testClassWithConstructor() {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_ClassWithConstructor.get());
assertEquals(TypedAbstractSyntax_ClassWithConstructor.get(), resultTypedAst);
}
}