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
| fieldVarAccess #Identifier
| stmtexpr #StatementExpressionexpr
| THIS #This
| NULL #Null
;

View File

@ -3,96 +3,104 @@ package de.maishai;
import de.maishai.antlr.DecafLexer;
import de.maishai.antlr.DecafParser;
import de.maishai.ast.records.Class;
import de.maishai.ast.records.Program;
import de.maishai.typedast.CodeGenUtils;
import de.maishai.typedast.typedclass.TypedClass;
import de.maishai.typedast.typedclass.TypedProgram;
import org.antlr.v4.runtime.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Decaf language 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) {
CharStream input = CharStreams.fromString(fromSource);
DecafLexer lexer = new DecafLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DecafParser parser = new DecafParser(tokens);
DecafParser.ClassContext tree = parser.class_(); //Parsen
return ASTGenerator.generateAST(tree);
}
public static Class generateASTFromFile(String sourcePath) {
ANTLRInputStream antlrInputStream;
try {
antlrInputStream = new ANTLRFileStream(sourcePath);
} catch (IOException e) {
System.out.println("Ungültiger Dateipfad D:");
throw new RuntimeException("Ungültiger Dateipfad D:");
public static Program generateAST(List<String> fromSources) {
List<Class> classes = new ArrayList<>();
for (String fromSource : fromSources) {
CharStream input = CharStreams.fromString(fromSource);
DecafLexer lexer = new DecafLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DecafParser parser = new DecafParser(tokens);
DecafParser.ClassContext tree = parser.class_(); //Parsen
classes.add(ASTGenerator.generateAST(tree));
}
return generateAST(antlrInputStream.toString());
return new Program(classes);
}
public static TypedClass generateTypedASTFromAst(Class ast) {
TypedClass typedAST = new TypedClass();
typedAST = (TypedClass) typedAST.startConversion(ast);
return typedAST;
public static Program generateASTFromFile(List<String> sourcePaths) {
List<String> sources = new ArrayList<>();
for (String sourcePath : sourcePaths) {
ANTLRInputStream antlrInputStream;
try {
antlrInputStream = new ANTLRFileStream(sourcePath);
} catch (IOException e) {
System.out.println("Ungültiger Dateipfad D:");
throw new RuntimeException("Ungültiger Dateipfad D:");
}
sources.add(antlrInputStream.toString());
}
return generateAST(sources);
}
public static TypedProgram generateTypedASTFromAst(Program ast) {
return new TypedProgram(ast);
}
public static byte[] generateByteCodeArrayFromTypedAst(TypedClass typedAST) {
return typedAST.codeGen();
}
public static byte[] generateByteCodeArray(String fromSource) {
Class ast = generateAST(fromSource);
TypedClass typedAST = generateTypedASTFromAst(ast);
return generateByteCodeArrayFromTypedAst(typedAST);
}
public static byte[] generateByteCodeArrayFromFile(String sourcePath) {
ANTLRInputStream antlrInputStream;
try {
antlrInputStream = new ANTLRFileStream(sourcePath);
} catch (IOException e) {
System.out.println("Ungültiger Dateipfad D:");
throw new RuntimeException("Ungültiger Dateipfad D:");
public static List<byte[]> generateByteCodeArray(List<String> fromSources) {
Program ast = generateAST(fromSources);
TypedProgram typedAST = generateTypedASTFromAst(ast);
List<byte[]> byteCode = new ArrayList<>();
for (TypedClass c : typedAST.getTypedClasses()) {
byteCode.add(generateByteCodeArrayFromTypedAst(c));
}
DecafLexer lexer = new DecafLexer(antlrInputStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DecafParser parser = new DecafParser(tokens);
DecafParser.ClassContext tree = parser.class_(); //Parsen
Class ast = ASTGenerator.generateAST(tree);
TypedClass typedAST = generateTypedASTFromAst(ast);
return generateByteCodeArrayFromTypedAst(typedAST);
return byteCode;
}
public static void generateByteCodeFileFromFile(String sourcePath, String classname) {
byte[] bytes = generateByteCodeArrayFromFile(sourcePath);
CodeGenUtils.writeClassfile(bytes, classname);
public static List<byte[]> generateByteCodeArrayFromFile(List<String> sourcePaths) {
List<Class> classes = new ArrayList<>();
for (String sourcePath : sourcePaths) {
ANTLRInputStream antlrInputStream;
try {
antlrInputStream = new ANTLRFileStream(sourcePath);
} catch (IOException e) {
System.out.println("Ungültiger Dateipfad D:");
throw new RuntimeException("Ungültiger Dateipfad D:");
}
DecafLexer lexer = new DecafLexer(antlrInputStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DecafParser parser = new DecafParser(tokens);
DecafParser.ClassContext tree = parser.class_(); //Parsen
Class ast = ASTGenerator.generateAST(tree);
classes.add(ast);
}
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(List<String> sourcePath, List<String> classname) {
List<byte[]> bytes = generateByteCodeArrayFromFile(sourcePath);
for (int i = 0; i < bytes.size(); i++) {
CodeGenUtils.writeClassfile(bytes.get(i), classname.get(i));
}
}
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) {
if (ctx.NUMBER() != null)
if (ctx.NUMBER() != null) {
return new IntLiteral(Integer.valueOf(ctx.NUMBER().getText()));
if (ctx.BOOLEANLITERAL() != null)
}
if (ctx.BOOLEANLITERAL() != null) {
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!");
}
@ -93,7 +99,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
recursiveOwnerChain = generateRecursiveOwnerChain(recipientList, null);
}
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()) {
Expression astExpr = expr.accept(this);
args.add(astExpr);
@ -115,6 +121,16 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
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) {
if (ctxList.isEmpty()) {
return recipient;
@ -123,7 +139,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
DecafParser.RecipientContext ctx = ctxList.get(lastElement);
ctxList.remove(lastElement);
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) {
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;
import org.antlr.v4.runtime.ParserRuleContext;
@ -360,6 +360,18 @@ public class DecafBaseListener implements DecafListener {
* <p>The default implementation does nothing.</p>
*/
@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}
*

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;
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>
*/
@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}
*

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

View File

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

View File

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

View File

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

View File

@ -1,59 +1,37 @@
package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Assignment;
import de.maishai.ast.records.Expression;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.TypedStatement;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@AllArgsConstructor
public class TypedAssignment implements TypedStatement {
private TypedExpression value;
private TypedFieldVarAccess location;
private Type type;
public TypedAssignment(TypedClass clas, Assignment untyped) {
convertToTypedAssignment(clas, untyped);
public TypedAssignment(TypedProgram typedProgram, Assignment untyped) {
convertToTypedAssignment(typedProgram, untyped);
}
public void convertToTypedAssignment(TypedClass clas, Assignment untyped) {
value = convertExpression(clas, untyped.value());
location = new TypedFieldVarAccess(clas, untyped.location());
location.typeCheck(clas);
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
value = convertExpression(typedProgram, untyped.value());
location = new TypedFieldVarAccess(typedProgram, untyped.location());
}
@Override
public Type typeCheck(TypedClass clas) {
Type typeLeft = null;
public Type typeCheck(TypedProgram typedProgram) {
if (clas.isThereField(location.getName())) {
typeLeft = clas.getFieldType(location.getName());
} 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);
Type typeLeft = getTypeLeft(typedProgram);
Type typeRight = value.typeCheck(typedProgram);
if (typeLeft.equals(typeRight)) {
type = typeLeft;
@ -62,6 +40,45 @@ public class TypedAssignment implements TypedStatement {
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
public void codeGen(MethodContext ctx) {
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.TypedExpression;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Label;
@ -17,26 +18,27 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedBinary implements TypedExpression {
private TypedExpression left;
private Operator op;
private TypedExpression right;
private Type type;
public TypedBinary(TypedClass clas, Binary unTypedBinary) {
convertToTypedBinary(clas, unTypedBinary);
public TypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
convertToTypedBinary(typedProgram, unTypedBinary);
}
public void convertToTypedBinary(TypedClass clas, Binary unTypedBinary) {
left = convertExpression(clas, unTypedBinary.left());
right = convertExpression(clas, unTypedBinary.right());
public void convertToTypedBinary(TypedProgram typedProgram, Binary unTypedBinary) {
left = convertExpression(typedProgram, unTypedBinary.left());
right = convertExpression(typedProgram, unTypedBinary.right());
op = unTypedBinary.op();
}
@Override
public Type typeCheck(TypedClass clas) {
Type leftType = left.typeCheck(clas);
Type rightType = right.typeCheck(clas);
public Type typeCheck(TypedProgram typedProgram) {
Type leftType = left.typeCheck(typedProgram);
Type rightType = right.typeCheck(typedProgram);
if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) {
if (leftType == Type.INT && rightType == Type.INT) {

View File

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

View File

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

View File

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

View File

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

View File

@ -14,9 +14,7 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
@ -31,43 +29,8 @@ public class TypedClass implements TypedNode {
private Type type;
public TypedClass(Class c) {
convertToTypedClass(c);
}
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;
className = c.classname();
type = Type.REFERENCE(className);
}
public boolean isParameterNameInCurrentConstructor(String parameterName) {
@ -82,28 +45,27 @@ public class TypedClass implements TypedNode {
return false;
}
public void convertToTypedClass(Class c) {
className = c.classname();
type = Type.REFERENCE(className);
public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
// 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
for (Declaration declaration : c.fieldDeclarations()) {
typedDeclarations.add(new TypedDeclaration(this, declaration));
typedDeclarations.add(new TypedDeclaration(typedProgram, declaration));
}
for (Constructor constructor : c.constructors()) {
typedConstructors.add(new TypedConstructor(this, constructor));
typedConstructors.add(new TypedConstructor(typedProgram, constructor));
}
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
int i = 0;
for (Constructor constructor : c.constructors()) {
enterCurrentConstructor(typedConstructors.get(i));
typedConstructors.get(i).convertToBlock(this, constructor);
typedConstructors.get(i).convertToBlock(typedProgram, constructor);
exitCurrentConstructor();
i++;
}
@ -111,24 +73,17 @@ public class TypedClass implements TypedNode {
int j = 0;
for (Method method : c.methods()) {
enterCurrentMethod(typedMethods.get(j));
typedMethods.get(j).convertToTypedBlock(this, method);
typedMethods.get(j).convertToTypedBlock(typedProgram, method);
exitCurrentMethod();
j++;
}
}
@Override
public Type typeCheck(TypedClass clas) {
public Type typeCheck(TypedProgram typedProgram) {
return type;
}
public TypedNode startConversion(Class c) {
Map<String, Type> local = new HashMap<>();
return new TypedClass(c);
}
public boolean isParameterWitNameInMethod(String parameterName) {
for (TypedMethod m : typedMethods) {
for (TypedParameter p : m.getTypedParameters()) {
@ -162,6 +117,24 @@ public class TypedClass implements TypedNode {
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) {
for (TypedParameter p : currentConstructor.getTypedParameters()) {
if (p.getParaName().equals(parameterName)) {
@ -189,13 +162,28 @@ public class TypedClass implements TypedNode {
return null;
}
public Type getMethodType(String methodName) {
for (TypedMethod m : typedMethods) {
if (m.getName().equals(methodName)) {
return m.getReturnType();
}
}
return null;
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;
}

View File

@ -29,8 +29,8 @@ public class TypedConstructor implements TypedNode {
this.typedBlock = typedBlock;
}
public TypedConstructor(TypedClass clas, Constructor unTypedConstructor) {
convertToTypedConstructor(clas, unTypedConstructor);
public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
convertToTypedConstructor(typedProgram, unTypedConstructor);
}
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();
}
public void convertToTypedConstructor(TypedClass clas, Constructor unTypedConstructor) {
public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
name = unTypedConstructor.className();
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;
}
public void convertToBlock(TypedClass clas, Constructor unTypedConstructor) {
this.typedBlock = new TypedBlock(clas, unTypedConstructor.block());
typeCheck(clas);
public void checkIfParameterExists(String paraName) {
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) {
throw new RuntimeException("Parameter " + paraName + " already exists");
}
}
public void convertToBlock(TypedProgram typedProgram, Constructor unTypedConstructor) {
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
typeCheck(typedProgram);
}
@Override
public Type typeCheck(TypedClass clas) {
type = typedBlock.typeCheck(clas);
public Type typeCheck(TypedProgram typedProgram) {
type = typedBlock.typeCheck(typedProgram);
if (type != Type.VOID) {
throw new RuntimeException("Constructor must not habe a return statement");
}

View File

@ -1,19 +1,14 @@
package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Declaration;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedNode;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Type.Kind.REFERENCE;
@Data
@AllArgsConstructor
@ -22,39 +17,29 @@ public final class TypedDeclaration implements TypedNode {
private String name;
private Type type;
public TypedDeclaration(TypedClass clas, Declaration declaration) {
convertToTypedDeclaration(clas, declaration);
public TypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
convertToTypedDeclaration(typedProgram, declaration);
}
public void convertToTypedDeclaration(TypedClass clas, Declaration declaration) {
public void convertToTypedDeclaration(TypedProgram typedProgram, Declaration declaration) {
name = declaration.name();
type = declaration.type();
typeCheck(clas);
typeCheck(typedProgram);
}
@Override
public Type typeCheck(TypedClass clas) {
if (clas.isThereField(name)) {
public Type typeCheck(TypedProgram typedProgram) {
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");
}
if (type.getKind() == REFERENCE) {
if (!type.getReference().equals(clas.getClassName())) {
throw new RuntimeException("Field " + name + " has wrong 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) {
int access = Opcodes.ACC_PUBLIC; // laut Andi ist es ok, dass alle Felder public sind
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.typedast.*;
import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -15,21 +12,21 @@ public class TypedDoWhile implements TypedStatement {
private TypedExpression cond;
private Type type;
public TypedDoWhile(TypedClass clas, DoWhile unTypedDoWhile) {
convertToTypedDoWhile(clas, unTypedDoWhile);
public TypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
convertToTypedDoWhile(typedProgram, unTypedDoWhile);
}
public void convertToTypedDoWhile(TypedClass clas, DoWhile unTypedDoWhile) {
typedBlock = new TypedBlock(clas, unTypedDoWhile.block());
cond = convertExpression(clas, unTypedDoWhile.cond());
public void convertToTypedDoWhile(TypedProgram typedProgram, DoWhile unTypedDoWhile) {
typedBlock = new TypedBlock(typedProgram, unTypedDoWhile.block());
cond = convertExpression(typedProgram, unTypedDoWhile.cond());
}
@Override
public Type typeCheck(TypedClass clas) {
if (cond.typeCheck(clas) != Type.BOOL) {
public Type typeCheck(TypedProgram typedProgram) {
if (cond.typeCheck(typedProgram) != Type.BOOL) {
throw new RuntimeException("Condition must be boolean");
}
typedBlock.typeCheck(clas);
typedBlock.typeCheck(typedProgram);
this.type = 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.TypedExpression;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
@ -15,66 +16,94 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedFieldVarAccess implements TypedExpression {
private Boolean field;
private TypedExpression recursiveOwnerChain;
private String name;
private Type type;
public TypedFieldVarAccess(TypedClass clas, FieldVarAccess unTypedFieldVarAccess) {
convertToTypedFieldVarAccess(clas, unTypedFieldVarAccess);
public TypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
convertToTypedFieldVarAccess(typedProgram, unTypedFieldVarAccess);
}
public void convertToTypedFieldVarAccess(TypedClass clas, FieldVarAccess unTypedFieldVarAccess) {
public void convertToTypedFieldVarAccess(TypedProgram typedProgram, FieldVarAccess unTypedFieldVarAccess) {
field = unTypedFieldVarAccess.field();
recursiveOwnerChain = convertExpression(clas, unTypedFieldVarAccess.recursiveOwnerChain());
recursiveOwnerChain = convertExpression(typedProgram, unTypedFieldVarAccess.recursiveOwnerChain());
name = unTypedFieldVarAccess.id();
}
@Override
public Type typeCheck(TypedClass clas) {
public Type typeCheck(TypedProgram typedProgram) {
if (field) {
if (clas.isThereField(name)) {
type = clas.getFieldType(name);
return clas.getFieldType(name);
}else{
throw new RuntimeException("Field " + name + " not declared ");
}
type = checkFieldOrMethodType(typedProgram);
return type;
} else {
if (clas.isCurrentConstructorPresent()) {
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;
}
else {
throw new RuntimeException("Variable " + name + " not declared in constructor");
}
} else if (clas.isCurrentMethodPresent()) {
if (clas.isParameterWitNameInMethod(name)) {
type = clas.getParameterTypeInCurrentMethod(name);
return type;
} else if (clas.getCurrentMethod().isLocalVariablePresent(name)) {
type = clas.getCurrentMethod().getLocalVariableType(name);
return type;
} else if(clas.isThereField(name)){
type = clas.getFieldType(name);
return type;
}
else {
throw new RuntimeException("Variable " + name + " not declared in method");
}
}
throw new RuntimeException("Variable " + name + " not declared ");
type = checkVariableType(typedProgram);
return type;
}
}
private Type checkFieldOrMethodType(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isThereField(name)) {
type = typedProgram.getCurrentClass().getFieldType(name);
return type;
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
type = typedProgram.getCurrentClass().getMethodType(name);
return type;
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
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;
}
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;
}
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
public void codeGen(MethodContext ctx) {
if (recursiveOwnerChain != null) {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,5 @@
package de.maishai.typedast.typedclass;
import de.maishai.ast.records.IfElse;
import de.maishai.ast.records.Method;
import de.maishai.typedast.*;
import lombok.Data;
@ -20,28 +19,37 @@ public class TypedMethod implements TypedNode {
private List<TypedLocalVariable> localVariables = new ArrayList<>();
private TypedBlock typedBlock;
public TypedMethod(TypedClass clas, Method unTypedMethod) {
convertToTypedMethod(clas, unTypedMethod);
public TypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
convertToTypedMethod(typedProgram, unTypedMethod);
}
public void convertToTypedMethod(TypedClass clas, Method unTypedMethod) {
public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
name = unTypedMethod.methodName();
returnType = unTypedMethod.type();
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 -> {
throw new RuntimeException("Method " + name + " already exists");
}, () -> {
});
}
public void convertToTypedBlock(TypedClass clas, Method unTypedMethod) {
typedBlock = new TypedBlock(clas, unTypedMethod.block());
typeCheck(clas);
public void checkIfParameterExists(String parameterName) {
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName))) {
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) {
@ -84,9 +92,9 @@ public class TypedMethod implements TypedNode {
}
@Override
public Type typeCheck(TypedClass clas) {
public Type typeCheck(TypedProgram typedProgram) {
if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) {
if (typedBlock.typeCheck(clas).getKind() != returnType.getKind()) {
if (typedBlock.typeCheck(typedProgram).getKind() != returnType.getKind()) {
if (hasEvenReturnsInIfElseBlocks()) {
throw new RuntimeException("Method " + name + " must have even returns in if else blocks");
} else {

View File

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

View File

@ -9,7 +9,6 @@ import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@ -18,30 +17,35 @@ public class TypedNew implements TypedExpression, TypedStatement {
private Type type;
private List<TypedExpression> args = new ArrayList<>();
public TypedNew(TypedClass clas, New unTypedNew) {
convertToTypedNew(clas, unTypedNew);
public TypedNew(TypedProgram typedProgram, New unTypedNew) {
convertToTypedNew(typedProgram, unTypedNew);
}
public void convertToTypedNew(TypedClass clas, New unTypedNew) {
public void convertToTypedNew(TypedProgram typedProgram, New unTypedNew) {
type = unTypedNew.type();
for (Expression arg : unTypedNew.args()) {
args.add(convertExpression(clas, arg));
args.add(convertExpression(typedProgram, arg));
}
}
@Override
public Type typeCheck(TypedClass clas) {
for (var constructor : clas.getTypedConstructors()) {
public Type typeCheck(TypedProgram typedProgram) {
if (typedProgram.isTypedClassPresent(type.getReference())) {
return Type.REFERENCE(type.getReference());
}
for (var constructor : typedProgram.getCurrentClass().getTypedConstructors()) {
if (constructor.getTypedParameters().size() == args.size()) {
boolean valid = true;
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;
break;
}
}
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.Data;
import java.util.Map;
@AllArgsConstructor
@Data
public class TypedParameter implements TypedNode {
private String paraName;
private Type type;
public TypedParameter(TypedClass clas, Parameter unTypedParameter) {
convertToTypedParameter(clas, unTypedParameter);
public TypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
convertToTypedParameter(typedProgram, unTypedParameter);
}
public void convertToTypedParameter(TypedClass clas, Parameter unTypedParameter) {
public void convertToTypedParameter(TypedProgram typedProgram, Parameter unTypedParameter) {
paraName = unTypedParameter.name();
type = unTypedParameter.type();
}
@ -34,14 +32,14 @@ public class TypedParameter implements TypedNode {
@Override
public Type typeCheck(TypedClass clas) {
public Type typeCheck(TypedProgram typedProgram) {
if (clas.isCurrentMethodPresent()) {
if (clas.isParameterWitNameInMethod(paraName)) {
if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (typedProgram.getCurrentClass().isParameterWitNameInMethod(paraName)) {
throw new RuntimeException("Parameter " + paraName + " already exists");
}
} else if (clas.isCurrentConstructorPresent()) {
if (clas.isParameterWitNameInConstructor(paraName)) {
} else if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
if (typedProgram.getCurrentClass().isParameterWitNameInConstructor(paraName)) {
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 lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@ -18,28 +15,28 @@ public class TypedReturn implements TypedStatement {
private TypedExpression ret;
private Type type;
public TypedReturn(TypedClass clas, Return unTypedReturn) {
convertToTypedReturn(clas, unTypedReturn);
public TypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
convertToTypedReturn(typedProgram, unTypedReturn);
}
public void convertToTypedReturn(TypedClass clas, Return unTypedReturn) {
ret = convertExpression(clas, unTypedReturn.ret());
if(ret == null){
public void convertToTypedReturn(TypedProgram typedProgram, Return unTypedReturn) {
ret = convertExpression(typedProgram, unTypedReturn.ret());
if (ret == null) {
type = Type.VOID;
}else{
} else {
type = ret.getType();
}
}
@Override
public Type typeCheck(TypedClass clas) {
if (clas.isCurrentMethodPresent()) {
if (clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
public Type typeCheck(TypedProgram typedProgram) {
if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
if (typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
StringBuilder exp = new StringBuilder();
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("\nMethod name: ").append(clas.getCurrentMethod().getName());
exp.append("\nMethod name: ").append(typedProgram.getCurrentClass().getCurrentMethod().getName());
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.Type;
import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.Map;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@ -19,28 +16,27 @@ public class TypedUnary implements TypedExpression {
private TypedExpression right;
private Type type;
public TypedUnary(TypedClass clas, Unary unTypedUnary) {
convertToTypedUnary(clas, unTypedUnary);
public TypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
convertToTypedUnary(typedProgram, unTypedUnary);
}
public void convertToTypedUnary(TypedClass clas, Unary unTypedUnary) {
public void convertToTypedUnary(TypedProgram typedProgram, Unary unTypedUnary) {
op = unTypedUnary.op();
right = convertExpression(clas, unTypedUnary.right());
type = right.getType();
right = convertExpression(typedProgram, unTypedUnary.right());
}
@Override
public Type typeCheck(TypedClass clas) {
public Type typeCheck(TypedProgram typedProgram) {
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");
}
return Type.BOOL;
}
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");
}
return Type.INT;
@ -51,11 +47,11 @@ public class TypedUnary implements TypedExpression {
@Override
public void codeGen(MethodContext ctx) {
right.codeGen(ctx);
if(op == UnaryOperator.NOT){
if (op == UnaryOperator.NOT) {
ctx.getMv().visitInsn(Opcodes.ICONST_1);
ctx.getMv().visitInsn(Opcodes.IXOR);
}
if(op == UnaryOperator.SUB){
if (op == UnaryOperator.SUB) {
ctx.getMv().visitInsn(Opcodes.INEG);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,19 +11,23 @@ import de.maishai.typedast.Type;
import java.util.List;
public class AbstractSyntax_ClassWithMethod {
public static Class get() {
public static Program get() {
List<Method> methods = getMethods();
return new Class(
"ClassWithMethod",
List.of(),
methods,
return new Program(
List.of(
new Constructor(
new Class(
"ClassWithMethod",
List.of(),
new Block(
List.of(),
List.of()
methods,
List.of(
new Constructor(
"ClassWithMethod",
List.of(),
new Block(
List.of(),
List.of()
)
)
)
)
)

View File

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

View File

@ -26,7 +26,7 @@ import de.maishai.typedast.Type;
import java.util.List;
public class AbstractSyntax_ClassWithMultipleMethods {
public static Class get() {
public static Program get() {
List<Declaration> declarations = List.of(
new Declaration(
"instance",
@ -35,11 +35,14 @@ public class AbstractSyntax_ClassWithMultipleMethods {
);
List<Method> methods = getMethods();
List<Constructor> constructors = List.of();
return new Class(
"ClassWithMoreComplexMethodAndMain",
declarations,
methods,
constructors
return new Program(
List.of(new Class(
"ClassWithMoreComplexMethodAndMain",
declarations,
methods,
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,22 +4,27 @@
import de.maishai.ast.records.Block;
import de.maishai.ast.records.Class;
import de.maishai.ast.records.Constructor;
import de.maishai.ast.records.Program;
import java.util.List;
public class AbstractSyntax_PublicClass {
public static Class get() {
return new Class(
"PublicClass",
List.of(),
List.of(),
public static Program get() {
return new Program(
List.of(
new Constructor(
new Class(
"PublicClass",
List.of(),
new Block(
List.of(),
List.of()
List.of(),
List.of(
new Constructor(
"PublicClass",
List.of(),
new Block(
List.of(),
List.of()
)
)
)
)
)

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

View File

@ -1,56 +1,64 @@
import de.maishai.Compiler;
import de.maishai.ast.records.Class;
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 ScannerParserTests {
@Test
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);
}
@Test
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);
}
@Test
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);
}
@Test
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);
}
@Test
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);
}
@Test
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);
}
@Test
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);
}
// @Test
// public void testClassWithConstructorAndMethodCall() {
// Class resultAst = Compiler.generateASTFromFile("src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java");
// assertEquals(AbstractSyntax_ClassWithConstructorAndMethodCall.get(), resultAst);
// }
@Test
public void testClassWithConstructorAndMethodCall() {
Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ClassWithConstructorAndMethodCall.java"));
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);
}
}