mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-27 09:28:03 +00:00
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:
commit
f1b366e157
BIN
output/ClassCanBeTyped.class
Normal file
BIN
output/ClassCanBeTyped.class
Normal file
Binary file not shown.
@ -38,6 +38,7 @@ expr : expr binaryOp expr #BinaryOperation
|
||||
| '(' expr ')' #Expression
|
||||
| fieldVarAccess #Identifier
|
||||
| stmtexpr #StatementExpressionexpr
|
||||
| THIS #This
|
||||
| NULL #Null
|
||||
;
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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}
|
||||
*
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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}.
|
||||
|
@ -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 {
|
||||
|
@ -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}.
|
||||
|
@ -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 {
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
|
5
src/main/java/de/maishai/ast/records/Null.java
Normal file
5
src/main/java/de/maishai/ast/records/Null.java
Normal file
@ -0,0 +1,5 @@
|
||||
package de.maishai.ast.records;
|
||||
|
||||
|
||||
public record Null() implements Expression {
|
||||
}
|
6
src/main/java/de/maishai/ast/records/Program.java
Normal file
6
src/main/java/de/maishai/ast/records/Program.java
Normal file
@ -0,0 +1,6 @@
|
||||
package de.maishai.ast.records;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Program(List<Class> classes) implements Node {
|
||||
}
|
5
src/main/java/de/maishai/ast/records/This.java
Normal file
5
src/main/java/de/maishai/ast/records/This.java
Normal file
@ -0,0 +1,5 @@
|
||||
package de.maishai.ast.records;
|
||||
|
||||
|
||||
public record This() implements Expression {
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
@ -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()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -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
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
@ -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()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
89
src/main/resources/JavaTestfiles/ComplexClass.java
Normal file
89
src/main/resources/JavaTestfiles/ComplexClass.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
16
src/test/java/CodegeneratorTests.java
Normal file
16
src/test/java/CodegeneratorTests.java
Normal 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);
|
||||
// }
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
public class E2ETests {
|
||||
char ZZ;
|
||||
|
||||
public E2ETests() {
|
||||
this.ZZ = 'z';
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
26
src/test/java/TypingTests.java
Normal file
26
src/test/java/TypingTests.java
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user