Compare commits

..

No commits in common. "patternMatching" and "targetBytecode" have entirely different histories.

62 changed files with 482 additions and 27319 deletions

View File

@ -15,7 +15,7 @@ jobs:
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '22' java-version: '21'
cache: 'maven' cache: 'maven'
- name: Compile project - name: Compile project
run: | run: |

File diff suppressed because one or more lines are too long

View File

@ -1,873 +0,0 @@
// Generated from C:/Users/ruben/IdeaProjects/JavaCompilerCore/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Lexer.g4 by ANTLR 4.13.1
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
public class Java17Lexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
ABSTRACT=1, ASSERT=2, BOOLEAN=3, BREAK=4, BYTE=5, CASE=6, CATCH=7, CHAR=8,
CLASS=9, CONST=10, CONTINUE=11, DEFAULT=12, DO=13, DOUBLE=14, ELSE=15,
ENUM=16, EXTENDS=17, FINAL=18, FINALLY=19, FLOAT=20, FOR=21, IF=22, GOTO=23,
IMPLEMENTS=24, IMPORT=25, INSTANCEOF=26, INT=27, INTERFACE=28, LONG=29,
NATIVE=30, NEW=31, PACKAGE=32, PRIVATE=33, PROTECTED=34, PUBLIC=35, RETURN=36,
SHORT=37, STATIC=38, STRICTFP=39, SUPER=40, SWITCH=41, SYNCHRONIZED=42,
THIS=43, THROW=44, THROWS=45, TRANSIENT=46, TRY=47, VOID=48, VOLATILE=49,
WHILE=50, MODULE=51, OPEN=52, REQUIRES=53, EXPORTS=54, OPENS=55, TO=56,
USES=57, PROVIDES=58, WITH=59, TRANSITIVE=60, VAR=61, YIELD=62, RECORD=63,
SEALED=64, PERMITS=65, NON_SEALED=66, DECIMAL_LITERAL=67, HEX_LITERAL=68,
OCT_LITERAL=69, BINARY_LITERAL=70, FLOAT_LITERAL=71, HEX_FLOAT_LITERAL=72,
BOOL_LITERAL=73, CHAR_LITERAL=74, STRING_LITERAL=75, TEXT_BLOCK=76, NULL_LITERAL=77,
LPAREN=78, RPAREN=79, LBRACE=80, RBRACE=81, LBRACK=82, RBRACK=83, SEMI=84,
COMMA=85, DOT=86, ASSIGN=87, GT=88, LT=89, BANG=90, TILDE=91, QUESTION=92,
COLON=93, EQUAL=94, LE=95, GE=96, NOTEQUAL=97, AND=98, OR=99, INC=100,
DEC=101, ADD=102, SUB=103, MUL=104, DIV=105, BITAND=106, BITOR=107, CARET=108,
MOD=109, ADD_ASSIGN=110, SUB_ASSIGN=111, MUL_ASSIGN=112, DIV_ASSIGN=113,
AND_ASSIGN=114, OR_ASSIGN=115, XOR_ASSIGN=116, MOD_ASSIGN=117, LSHIFT_ASSIGN=118,
RSHIFT_ASSIGN=119, URSHIFT_ASSIGN=120, ARROW=121, COLONCOLON=122, AT=123,
ELLIPSIS=124, WS=125, COMMENT=126, LINE_COMMENT=127, IDENTIFIER=128;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR",
"CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM",
"EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO", "IMPLEMENTS",
"IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW",
"PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC",
"STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS",
"TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "MODULE", "OPEN", "REQUIRES",
"EXPORTS", "OPENS", "TO", "USES", "PROVIDES", "WITH", "TRANSITIVE", "VAR",
"YIELD", "RECORD", "SEALED", "PERMITS", "NON_SEALED", "DECIMAL_LITERAL",
"HEX_LITERAL", "OCT_LITERAL", "BINARY_LITERAL", "FLOAT_LITERAL", "HEX_FLOAT_LITERAL",
"BOOL_LITERAL", "CHAR_LITERAL", "STRING_LITERAL", "TEXT_BLOCK", "NULL_LITERAL",
"LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", "SEMI", "COMMA",
"DOT", "ASSIGN", "GT", "LT", "BANG", "TILDE", "QUESTION", "COLON", "EQUAL",
"LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", "SUB", "MUL",
"DIV", "BITAND", "BITOR", "CARET", "MOD", "ADD_ASSIGN", "SUB_ASSIGN",
"MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN",
"MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ARROW",
"COLONCOLON", "AT", "ELLIPSIS", "WS", "COMMENT", "LINE_COMMENT", "IDENTIFIER",
"ExponentPart", "EscapeSequence", "HexDigits", "HexDigit", "Digits",
"LetterOrDigit", "Letter"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, "'abstract'", "'assert'", "'boolean'", "'break'", "'byte'", "'case'",
"'catch'", "'char'", "'class'", "'const'", "'continue'", "'default'",
"'do'", "'double'", "'else'", "'enum'", "'extends'", "'final'", "'finally'",
"'float'", "'for'", "'if'", "'goto'", "'implements'", "'import'", "'instanceof'",
"'int'", "'interface'", "'long'", "'native'", "'new'", "'package'", "'private'",
"'protected'", "'public'", "'return'", "'short'", "'static'", "'strictfp'",
"'super'", "'switch'", "'synchronized'", "'this'", "'throw'", "'throws'",
"'transient'", "'try'", "'void'", "'volatile'", "'while'", "'module'",
"'open'", "'requires'", "'exports'", "'opens'", "'to'", "'uses'", "'provides'",
"'with'", "'transitive'", "'var'", "'yield'", "'record'", "'sealed'",
"'permits'", "'non-sealed'", null, null, null, null, null, null, null,
null, null, null, "'null'", "'('", "')'", "'{'", "'}'", "'['", "']'",
"';'", "','", "'.'", "'='", "'>'", "'<'", "'!'", "'~'", "'?'", "':'",
"'=='", "'<='", "'>='", "'!='", "'&&'", "'||'", "'++'", "'--'", "'+'",
"'-'", "'*'", "'/'", "'&'", "'|'", "'^'", "'%'", "'+='", "'-='", "'*='",
"'/='", "'&='", "'|='", "'^='", "'%='", "'<<='", "'>>='", "'>>>='", "'->'",
"'::'", "'@'", "'...'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH",
"CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE",
"ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO",
"IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE",
"NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT",
"STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW",
"THROWS", "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "MODULE",
"OPEN", "REQUIRES", "EXPORTS", "OPENS", "TO", "USES", "PROVIDES", "WITH",
"TRANSITIVE", "VAR", "YIELD", "RECORD", "SEALED", "PERMITS", "NON_SEALED",
"DECIMAL_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BINARY_LITERAL", "FLOAT_LITERAL",
"HEX_FLOAT_LITERAL", "BOOL_LITERAL", "CHAR_LITERAL", "STRING_LITERAL",
"TEXT_BLOCK", "NULL_LITERAL", "LPAREN", "RPAREN", "LBRACE", "RBRACE",
"LBRACK", "RBRACK", "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "BANG",
"TILDE", "QUESTION", "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND",
"OR", "INC", "DEC", "ADD", "SUB", "MUL", "DIV", "BITAND", "BITOR", "CARET",
"MOD", "ADD_ASSIGN", "SUB_ASSIGN", "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN",
"OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN",
"URSHIFT_ASSIGN", "ARROW", "COLONCOLON", "AT", "ELLIPSIS", "WS", "COMMENT",
"LINE_COMMENT", "IDENTIFIER"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public Java17Lexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "Java17Lexer.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\u0004\u0000\u0080\u0458\u0006\uffff\uffff\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\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+
"\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+
"\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+
"\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+
"\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+
"\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+
"\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+
"\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002"+
"&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002"+
"+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u0002"+
"0\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0002"+
"5\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002"+
":\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002"+
"?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002"+
"D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002"+
"I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002"+
"N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002"+
"S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002"+
"X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002"+
"]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002"+
"b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002"+
"g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002"+
"l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002"+
"q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002"+
"v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002"+
"{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f"+
"\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082"+
"\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085"+
"\u0002\u0086\u0007\u0086\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
"\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001"+
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
"\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
"\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
"\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+
"\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
"\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+
"\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+
"\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
"\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
"\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\r\u0001"+
"\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001"+
"\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+
"\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+
"\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001"+
"\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001"+
"\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001"+
"\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001"+
"\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001"+
"\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
"\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001"+
"\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001"+
"\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+
"\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001"+
"\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001"+
"\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
"\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
"\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001"+
"\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001"+
"\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001"+
"\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001"+
"\u001f\u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001!"+
"\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001"+
"\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001"+
"#\u0001#\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0001$\u0001"+
"$\u0001%\u0001%\u0001%\u0001%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001"+
"&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001"+
"\'\u0001\'\u0001\'\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001"+
")\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001"+
")\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001"+
"+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001"+
",\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001"+
"-\u0001.\u0001.\u0001.\u0001.\u0001/\u0001/\u0001/\u0001/\u0001/\u0001"+
"0\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00011\u0001"+
"1\u00011\u00011\u00011\u00011\u00012\u00012\u00012\u00012\u00012\u0001"+
"2\u00012\u00013\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u0001"+
"4\u00014\u00014\u00014\u00014\u00014\u00015\u00015\u00015\u00015\u0001"+
"5\u00015\u00015\u00015\u00016\u00016\u00016\u00016\u00016\u00016\u0001"+
"7\u00017\u00017\u00018\u00018\u00018\u00018\u00018\u00019\u00019\u0001"+
"9\u00019\u00019\u00019\u00019\u00019\u00019\u0001:\u0001:\u0001:\u0001"+
":\u0001:\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001"+
";\u0001;\u0001;\u0001<\u0001<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001"+
"=\u0001=\u0001=\u0001>\u0001>\u0001>\u0001>\u0001>\u0001>\u0001>\u0001"+
"?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001@\u0001@\u0001@\u0001"+
"@\u0001@\u0001@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001A\u0001A\u0001"+
"A\u0001A\u0001A\u0001A\u0001A\u0001A\u0001B\u0001B\u0001B\u0003B\u02d5"+
"\bB\u0001B\u0004B\u02d8\bB\u000bB\fB\u02d9\u0001B\u0003B\u02dd\bB\u0003"+
"B\u02df\bB\u0001B\u0003B\u02e2\bB\u0001C\u0001C\u0001C\u0001C\u0005C\u02e8"+
"\bC\nC\fC\u02eb\tC\u0001C\u0003C\u02ee\bC\u0001C\u0003C\u02f1\bC\u0001"+
"D\u0001D\u0005D\u02f5\bD\nD\fD\u02f8\tD\u0001D\u0001D\u0005D\u02fc\bD"+
"\nD\fD\u02ff\tD\u0001D\u0003D\u0302\bD\u0001D\u0003D\u0305\bD\u0001E\u0001"+
"E\u0001E\u0001E\u0005E\u030b\bE\nE\fE\u030e\tE\u0001E\u0003E\u0311\bE"+
"\u0001E\u0003E\u0314\bE\u0001F\u0001F\u0001F\u0003F\u0319\bF\u0001F\u0001"+
"F\u0003F\u031d\bF\u0001F\u0003F\u0320\bF\u0001F\u0003F\u0323\bF\u0001"+
"F\u0001F\u0001F\u0003F\u0328\bF\u0001F\u0003F\u032b\bF\u0003F\u032d\b"+
"F\u0001G\u0001G\u0001G\u0001G\u0003G\u0333\bG\u0001G\u0003G\u0336\bG\u0001"+
"G\u0001G\u0003G\u033a\bG\u0001G\u0001G\u0003G\u033e\bG\u0001G\u0001G\u0003"+
"G\u0342\bG\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001"+
"H\u0003H\u034d\bH\u0001I\u0001I\u0001I\u0003I\u0352\bI\u0001I\u0001I\u0001"+
"J\u0001J\u0001J\u0005J\u0359\bJ\nJ\fJ\u035c\tJ\u0001J\u0001J\u0001K\u0001"+
"K\u0001K\u0001K\u0001K\u0005K\u0365\bK\nK\fK\u0368\tK\u0001K\u0001K\u0001"+
"K\u0005K\u036d\bK\nK\fK\u0370\tK\u0001K\u0001K\u0001K\u0001K\u0001L\u0001"+
"L\u0001L\u0001L\u0001L\u0001M\u0001M\u0001N\u0001N\u0001O\u0001O\u0001"+
"P\u0001P\u0001Q\u0001Q\u0001R\u0001R\u0001S\u0001S\u0001T\u0001T\u0001"+
"U\u0001U\u0001V\u0001V\u0001W\u0001W\u0001X\u0001X\u0001Y\u0001Y\u0001"+
"Z\u0001Z\u0001[\u0001[\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001^\u0001"+
"^\u0001^\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001a\u0001a\u0001"+
"a\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001d\u0001d\u0001d\u0001"+
"e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001i\u0001"+
"j\u0001j\u0001k\u0001k\u0001l\u0001l\u0001m\u0001m\u0001m\u0001n\u0001"+
"n\u0001n\u0001o\u0001o\u0001o\u0001p\u0001p\u0001p\u0001q\u0001q\u0001"+
"q\u0001r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001"+
"u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001v\u0001w\u0001w\u0001"+
"w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001z\u0001"+
"z\u0001{\u0001{\u0001{\u0001{\u0001|\u0004|\u03f5\b|\u000b|\f|\u03f6\u0001"+
"|\u0001|\u0001}\u0001}\u0001}\u0001}\u0005}\u03ff\b}\n}\f}\u0402\t}\u0001"+
"}\u0001}\u0001}\u0001}\u0001}\u0001~\u0001~\u0001~\u0001~\u0005~\u040d"+
"\b~\n~\f~\u0410\t~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0005\u007f\u0416"+
"\b\u007f\n\u007f\f\u007f\u0419\t\u007f\u0001\u0080\u0001\u0080\u0003\u0080"+
"\u041d\b\u0080\u0001\u0080\u0001\u0080\u0001\u0081\u0001\u0081\u0001\u0081"+
"\u0001\u0081\u0003\u0081\u0425\b\u0081\u0001\u0081\u0003\u0081\u0428\b"+
"\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0004\u0081\u042d\b\u0081\u000b"+
"\u0081\f\u0081\u042e\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001"+
"\u0081\u0003\u0081\u0436\b\u0081\u0001\u0082\u0001\u0082\u0001\u0082\u0005"+
"\u0082\u043b\b\u0082\n\u0082\f\u0082\u043e\t\u0082\u0001\u0082\u0003\u0082"+
"\u0441\b\u0082\u0001\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0005\u0084"+
"\u0447\b\u0084\n\u0084\f\u0084\u044a\t\u0084\u0001\u0084\u0003\u0084\u044d"+
"\b\u0084\u0001\u0085\u0001\u0085\u0003\u0085\u0451\b\u0085\u0001\u0086"+
"\u0001\u0086\u0001\u0086\u0001\u0086\u0003\u0086\u0457\b\u0086\u0002\u036e"+
"\u0400\u0000\u0087\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005"+
"\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017\f\u0019"+
"\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013\'\u0014)\u0015"+
"+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d;\u001e=\u001f"+
"? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e3g4i5k6m7o8q9s:u;w<y={>}?\u007f"+
"@\u0081A\u0083B\u0085C\u0087D\u0089E\u008bF\u008dG\u008fH\u0091I\u0093"+
"J\u0095K\u0097L\u0099M\u009bN\u009dO\u009fP\u00a1Q\u00a3R\u00a5S\u00a7"+
"T\u00a9U\u00abV\u00adW\u00afX\u00b1Y\u00b3Z\u00b5[\u00b7\\\u00b9]\u00bb"+
"^\u00bd_\u00bf`\u00c1a\u00c3b\u00c5c\u00c7d\u00c9e\u00cbf\u00cdg\u00cf"+
"h\u00d1i\u00d3j\u00d5k\u00d7l\u00d9m\u00dbn\u00ddo\u00dfp\u00e1q\u00e3"+
"r\u00e5s\u00e7t\u00e9u\u00ebv\u00edw\u00efx\u00f1y\u00f3z\u00f5{\u00f7"+
"|\u00f9}\u00fb~\u00fd\u007f\u00ff\u0080\u0101\u0000\u0103\u0000\u0105"+
"\u0000\u0107\u0000\u0109\u0000\u010b\u0000\u010d\u0000\u0001\u0000\u001b"+
"\u0001\u000019\u0002\u0000LLll\u0002\u0000XXxx\u0003\u000009AFaf\u0004"+
"\u000009AF__af\u0001\u000007\u0002\u000007__\u0002\u0000BBbb\u0001\u0000"+
"01\u0002\u000001__\u0004\u0000DDFFddff\u0002\u0000PPpp\u0002\u0000++-"+
"-\u0004\u0000\n\n\r\r\'\'\\\\\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000"+
"\t\t \u0002\u0000\n\n\r\r\u0003\u0000\t\n\f\r \u0002\u0000EEee\b\u0000"+
"\"\"\'\'\\\\bbffnnrrtt\u0001\u000003\u0001\u000009\u0002\u000009__\u0004"+
"\u0000$$AZ__az\u0002\u0000\u0000\u007f\u8000\ud800\u8000\udbff\u0001\u0000"+
"\u8000\ud800\u8000\udbff\u0001\u0000\u8000\udc00\u8000\udfff\u0484\u0000"+
"\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000"+
"\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000"+
"\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r"+
"\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011"+
"\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015"+
"\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019"+
"\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d"+
"\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001"+
"\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000"+
"\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000"+
"\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000\u0000\u0000/"+
"\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u00003\u0001\u0000"+
"\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001\u0000\u0000\u0000"+
"\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000\u0000\u0000="+
"\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000A\u0001\u0000"+
"\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0000E\u0001\u0000\u0000\u0000"+
"\u0000G\u0001\u0000\u0000\u0000\u0000I\u0001\u0000\u0000\u0000\u0000K"+
"\u0001\u0000\u0000\u0000\u0000M\u0001\u0000\u0000\u0000\u0000O\u0001\u0000"+
"\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001\u0000\u0000\u0000"+
"\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000\u0000Y"+
"\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000]\u0001\u0000"+
"\u0000\u0000\u0000_\u0001\u0000\u0000\u0000\u0000a\u0001\u0000\u0000\u0000"+
"\u0000c\u0001\u0000\u0000\u0000\u0000e\u0001\u0000\u0000\u0000\u0000g"+
"\u0001\u0000\u0000\u0000\u0000i\u0001\u0000\u0000\u0000\u0000k\u0001\u0000"+
"\u0000\u0000\u0000m\u0001\u0000\u0000\u0000\u0000o\u0001\u0000\u0000\u0000"+
"\u0000q\u0001\u0000\u0000\u0000\u0000s\u0001\u0000\u0000\u0000\u0000u"+
"\u0001\u0000\u0000\u0000\u0000w\u0001\u0000\u0000\u0000\u0000y\u0001\u0000"+
"\u0000\u0000\u0000{\u0001\u0000\u0000\u0000\u0000}\u0001\u0000\u0000\u0000"+
"\u0000\u007f\u0001\u0000\u0000\u0000\u0000\u0081\u0001\u0000\u0000\u0000"+
"\u0000\u0083\u0001\u0000\u0000\u0000\u0000\u0085\u0001\u0000\u0000\u0000"+
"\u0000\u0087\u0001\u0000\u0000\u0000\u0000\u0089\u0001\u0000\u0000\u0000"+
"\u0000\u008b\u0001\u0000\u0000\u0000\u0000\u008d\u0001\u0000\u0000\u0000"+
"\u0000\u008f\u0001\u0000\u0000\u0000\u0000\u0091\u0001\u0000\u0000\u0000"+
"\u0000\u0093\u0001\u0000\u0000\u0000\u0000\u0095\u0001\u0000\u0000\u0000"+
"\u0000\u0097\u0001\u0000\u0000\u0000\u0000\u0099\u0001\u0000\u0000\u0000"+
"\u0000\u009b\u0001\u0000\u0000\u0000\u0000\u009d\u0001\u0000\u0000\u0000"+
"\u0000\u009f\u0001\u0000\u0000\u0000\u0000\u00a1\u0001\u0000\u0000\u0000"+
"\u0000\u00a3\u0001\u0000\u0000\u0000\u0000\u00a5\u0001\u0000\u0000\u0000"+
"\u0000\u00a7\u0001\u0000\u0000\u0000\u0000\u00a9\u0001\u0000\u0000\u0000"+
"\u0000\u00ab\u0001\u0000\u0000\u0000\u0000\u00ad\u0001\u0000\u0000\u0000"+
"\u0000\u00af\u0001\u0000\u0000\u0000\u0000\u00b1\u0001\u0000\u0000\u0000"+
"\u0000\u00b3\u0001\u0000\u0000\u0000\u0000\u00b5\u0001\u0000\u0000\u0000"+
"\u0000\u00b7\u0001\u0000\u0000\u0000\u0000\u00b9\u0001\u0000\u0000\u0000"+
"\u0000\u00bb\u0001\u0000\u0000\u0000\u0000\u00bd\u0001\u0000\u0000\u0000"+
"\u0000\u00bf\u0001\u0000\u0000\u0000\u0000\u00c1\u0001\u0000\u0000\u0000"+
"\u0000\u00c3\u0001\u0000\u0000\u0000\u0000\u00c5\u0001\u0000\u0000\u0000"+
"\u0000\u00c7\u0001\u0000\u0000\u0000\u0000\u00c9\u0001\u0000\u0000\u0000"+
"\u0000\u00cb\u0001\u0000\u0000\u0000\u0000\u00cd\u0001\u0000\u0000\u0000"+
"\u0000\u00cf\u0001\u0000\u0000\u0000\u0000\u00d1\u0001\u0000\u0000\u0000"+
"\u0000\u00d3\u0001\u0000\u0000\u0000\u0000\u00d5\u0001\u0000\u0000\u0000"+
"\u0000\u00d7\u0001\u0000\u0000\u0000\u0000\u00d9\u0001\u0000\u0000\u0000"+
"\u0000\u00db\u0001\u0000\u0000\u0000\u0000\u00dd\u0001\u0000\u0000\u0000"+
"\u0000\u00df\u0001\u0000\u0000\u0000\u0000\u00e1\u0001\u0000\u0000\u0000"+
"\u0000\u00e3\u0001\u0000\u0000\u0000\u0000\u00e5\u0001\u0000\u0000\u0000"+
"\u0000\u00e7\u0001\u0000\u0000\u0000\u0000\u00e9\u0001\u0000\u0000\u0000"+
"\u0000\u00eb\u0001\u0000\u0000\u0000\u0000\u00ed\u0001\u0000\u0000\u0000"+
"\u0000\u00ef\u0001\u0000\u0000\u0000\u0000\u00f1\u0001\u0000\u0000\u0000"+
"\u0000\u00f3\u0001\u0000\u0000\u0000\u0000\u00f5\u0001\u0000\u0000\u0000"+
"\u0000\u00f7\u0001\u0000\u0000\u0000\u0000\u00f9\u0001\u0000\u0000\u0000"+
"\u0000\u00fb\u0001\u0000\u0000\u0000\u0000\u00fd\u0001\u0000\u0000\u0000"+
"\u0000\u00ff\u0001\u0000\u0000\u0000\u0001\u010f\u0001\u0000\u0000\u0000"+
"\u0003\u0118\u0001\u0000\u0000\u0000\u0005\u011f\u0001\u0000\u0000\u0000"+
"\u0007\u0127\u0001\u0000\u0000\u0000\t\u012d\u0001\u0000\u0000\u0000\u000b"+
"\u0132\u0001\u0000\u0000\u0000\r\u0137\u0001\u0000\u0000\u0000\u000f\u013d"+
"\u0001\u0000\u0000\u0000\u0011\u0142\u0001\u0000\u0000\u0000\u0013\u0148"+
"\u0001\u0000\u0000\u0000\u0015\u014e\u0001\u0000\u0000\u0000\u0017\u0157"+
"\u0001\u0000\u0000\u0000\u0019\u015f\u0001\u0000\u0000\u0000\u001b\u0162"+
"\u0001\u0000\u0000\u0000\u001d\u0169\u0001\u0000\u0000\u0000\u001f\u016e"+
"\u0001\u0000\u0000\u0000!\u0173\u0001\u0000\u0000\u0000#\u017b\u0001\u0000"+
"\u0000\u0000%\u0181\u0001\u0000\u0000\u0000\'\u0189\u0001\u0000\u0000"+
"\u0000)\u018f\u0001\u0000\u0000\u0000+\u0193\u0001\u0000\u0000\u0000-"+
"\u0196\u0001\u0000\u0000\u0000/\u019b\u0001\u0000\u0000\u00001\u01a6\u0001"+
"\u0000\u0000\u00003\u01ad\u0001\u0000\u0000\u00005\u01b8\u0001\u0000\u0000"+
"\u00007\u01bc\u0001\u0000\u0000\u00009\u01c6\u0001\u0000\u0000\u0000;"+
"\u01cb\u0001\u0000\u0000\u0000=\u01d2\u0001\u0000\u0000\u0000?\u01d6\u0001"+
"\u0000\u0000\u0000A\u01de\u0001\u0000\u0000\u0000C\u01e6\u0001\u0000\u0000"+
"\u0000E\u01f0\u0001\u0000\u0000\u0000G\u01f7\u0001\u0000\u0000\u0000I"+
"\u01fe\u0001\u0000\u0000\u0000K\u0204\u0001\u0000\u0000\u0000M\u020b\u0001"+
"\u0000\u0000\u0000O\u0214\u0001\u0000\u0000\u0000Q\u021a\u0001\u0000\u0000"+
"\u0000S\u0221\u0001\u0000\u0000\u0000U\u022e\u0001\u0000\u0000\u0000W"+
"\u0233\u0001\u0000\u0000\u0000Y\u0239\u0001\u0000\u0000\u0000[\u0240\u0001"+
"\u0000\u0000\u0000]\u024a\u0001\u0000\u0000\u0000_\u024e\u0001\u0000\u0000"+
"\u0000a\u0253\u0001\u0000\u0000\u0000c\u025c\u0001\u0000\u0000\u0000e"+
"\u0262\u0001\u0000\u0000\u0000g\u0269\u0001\u0000\u0000\u0000i\u026e\u0001"+
"\u0000\u0000\u0000k\u0277\u0001\u0000\u0000\u0000m\u027f\u0001\u0000\u0000"+
"\u0000o\u0285\u0001\u0000\u0000\u0000q\u0288\u0001\u0000\u0000\u0000s"+
"\u028d\u0001\u0000\u0000\u0000u\u0296\u0001\u0000\u0000\u0000w\u029b\u0001"+
"\u0000\u0000\u0000y\u02a6\u0001\u0000\u0000\u0000{\u02aa\u0001\u0000\u0000"+
"\u0000}\u02b0\u0001\u0000\u0000\u0000\u007f\u02b7\u0001\u0000\u0000\u0000"+
"\u0081\u02be\u0001\u0000\u0000\u0000\u0083\u02c6\u0001\u0000\u0000\u0000"+
"\u0085\u02de\u0001\u0000\u0000\u0000\u0087\u02e3\u0001\u0000\u0000\u0000"+
"\u0089\u02f2\u0001\u0000\u0000\u0000\u008b\u0306\u0001\u0000\u0000\u0000"+
"\u008d\u032c\u0001\u0000\u0000\u0000\u008f\u032e\u0001\u0000\u0000\u0000"+
"\u0091\u034c\u0001\u0000\u0000\u0000\u0093\u034e\u0001\u0000\u0000\u0000"+
"\u0095\u0355\u0001\u0000\u0000\u0000\u0097\u035f\u0001\u0000\u0000\u0000"+
"\u0099\u0375\u0001\u0000\u0000\u0000\u009b\u037a\u0001\u0000\u0000\u0000"+
"\u009d\u037c\u0001\u0000\u0000\u0000\u009f\u037e\u0001\u0000\u0000\u0000"+
"\u00a1\u0380\u0001\u0000\u0000\u0000\u00a3\u0382\u0001\u0000\u0000\u0000"+
"\u00a5\u0384\u0001\u0000\u0000\u0000\u00a7\u0386\u0001\u0000\u0000\u0000"+
"\u00a9\u0388\u0001\u0000\u0000\u0000\u00ab\u038a\u0001\u0000\u0000\u0000"+
"\u00ad\u038c\u0001\u0000\u0000\u0000\u00af\u038e\u0001\u0000\u0000\u0000"+
"\u00b1\u0390\u0001\u0000\u0000\u0000\u00b3\u0392\u0001\u0000\u0000\u0000"+
"\u00b5\u0394\u0001\u0000\u0000\u0000\u00b7\u0396\u0001\u0000\u0000\u0000"+
"\u00b9\u0398\u0001\u0000\u0000\u0000\u00bb\u039a\u0001\u0000\u0000\u0000"+
"\u00bd\u039d\u0001\u0000\u0000\u0000\u00bf\u03a0\u0001\u0000\u0000\u0000"+
"\u00c1\u03a3\u0001\u0000\u0000\u0000\u00c3\u03a6\u0001\u0000\u0000\u0000"+
"\u00c5\u03a9\u0001\u0000\u0000\u0000\u00c7\u03ac\u0001\u0000\u0000\u0000"+
"\u00c9\u03af\u0001\u0000\u0000\u0000\u00cb\u03b2\u0001\u0000\u0000\u0000"+
"\u00cd\u03b4\u0001\u0000\u0000\u0000\u00cf\u03b6\u0001\u0000\u0000\u0000"+
"\u00d1\u03b8\u0001\u0000\u0000\u0000\u00d3\u03ba\u0001\u0000\u0000\u0000"+
"\u00d5\u03bc\u0001\u0000\u0000\u0000\u00d7\u03be\u0001\u0000\u0000\u0000"+
"\u00d9\u03c0\u0001\u0000\u0000\u0000\u00db\u03c2\u0001\u0000\u0000\u0000"+
"\u00dd\u03c5\u0001\u0000\u0000\u0000\u00df\u03c8\u0001\u0000\u0000\u0000"+
"\u00e1\u03cb\u0001\u0000\u0000\u0000\u00e3\u03ce\u0001\u0000\u0000\u0000"+
"\u00e5\u03d1\u0001\u0000\u0000\u0000\u00e7\u03d4\u0001\u0000\u0000\u0000"+
"\u00e9\u03d7\u0001\u0000\u0000\u0000\u00eb\u03da\u0001\u0000\u0000\u0000"+
"\u00ed\u03de\u0001\u0000\u0000\u0000\u00ef\u03e2\u0001\u0000\u0000\u0000"+
"\u00f1\u03e7\u0001\u0000\u0000\u0000\u00f3\u03ea\u0001\u0000\u0000\u0000"+
"\u00f5\u03ed\u0001\u0000\u0000\u0000\u00f7\u03ef\u0001\u0000\u0000\u0000"+
"\u00f9\u03f4\u0001\u0000\u0000\u0000\u00fb\u03fa\u0001\u0000\u0000\u0000"+
"\u00fd\u0408\u0001\u0000\u0000\u0000\u00ff\u0413\u0001\u0000\u0000\u0000"+
"\u0101\u041a\u0001\u0000\u0000\u0000\u0103\u0435\u0001\u0000\u0000\u0000"+
"\u0105\u0437\u0001\u0000\u0000\u0000\u0107\u0442\u0001\u0000\u0000\u0000"+
"\u0109\u0444\u0001\u0000\u0000\u0000\u010b\u0450\u0001\u0000\u0000\u0000"+
"\u010d\u0456\u0001\u0000\u0000\u0000\u010f\u0110\u0005a\u0000\u0000\u0110"+
"\u0111\u0005b\u0000\u0000\u0111\u0112\u0005s\u0000\u0000\u0112\u0113\u0005"+
"t\u0000\u0000\u0113\u0114\u0005r\u0000\u0000\u0114\u0115\u0005a\u0000"+
"\u0000\u0115\u0116\u0005c\u0000\u0000\u0116\u0117\u0005t\u0000\u0000\u0117"+
"\u0002\u0001\u0000\u0000\u0000\u0118\u0119\u0005a\u0000\u0000\u0119\u011a"+
"\u0005s\u0000\u0000\u011a\u011b\u0005s\u0000\u0000\u011b\u011c\u0005e"+
"\u0000\u0000\u011c\u011d\u0005r\u0000\u0000\u011d\u011e\u0005t\u0000\u0000"+
"\u011e\u0004\u0001\u0000\u0000\u0000\u011f\u0120\u0005b\u0000\u0000\u0120"+
"\u0121\u0005o\u0000\u0000\u0121\u0122\u0005o\u0000\u0000\u0122\u0123\u0005"+
"l\u0000\u0000\u0123\u0124\u0005e\u0000\u0000\u0124\u0125\u0005a\u0000"+
"\u0000\u0125\u0126\u0005n\u0000\u0000\u0126\u0006\u0001\u0000\u0000\u0000"+
"\u0127\u0128\u0005b\u0000\u0000\u0128\u0129\u0005r\u0000\u0000\u0129\u012a"+
"\u0005e\u0000\u0000\u012a\u012b\u0005a\u0000\u0000\u012b\u012c\u0005k"+
"\u0000\u0000\u012c\b\u0001\u0000\u0000\u0000\u012d\u012e\u0005b\u0000"+
"\u0000\u012e\u012f\u0005y\u0000\u0000\u012f\u0130\u0005t\u0000\u0000\u0130"+
"\u0131\u0005e\u0000\u0000\u0131\n\u0001\u0000\u0000\u0000\u0132\u0133"+
"\u0005c\u0000\u0000\u0133\u0134\u0005a\u0000\u0000\u0134\u0135\u0005s"+
"\u0000\u0000\u0135\u0136\u0005e\u0000\u0000\u0136\f\u0001\u0000\u0000"+
"\u0000\u0137\u0138\u0005c\u0000\u0000\u0138\u0139\u0005a\u0000\u0000\u0139"+
"\u013a\u0005t\u0000\u0000\u013a\u013b\u0005c\u0000\u0000\u013b\u013c\u0005"+
"h\u0000\u0000\u013c\u000e\u0001\u0000\u0000\u0000\u013d\u013e\u0005c\u0000"+
"\u0000\u013e\u013f\u0005h\u0000\u0000\u013f\u0140\u0005a\u0000\u0000\u0140"+
"\u0141\u0005r\u0000\u0000\u0141\u0010\u0001\u0000\u0000\u0000\u0142\u0143"+
"\u0005c\u0000\u0000\u0143\u0144\u0005l\u0000\u0000\u0144\u0145\u0005a"+
"\u0000\u0000\u0145\u0146\u0005s\u0000\u0000\u0146\u0147\u0005s\u0000\u0000"+
"\u0147\u0012\u0001\u0000\u0000\u0000\u0148\u0149\u0005c\u0000\u0000\u0149"+
"\u014a\u0005o\u0000\u0000\u014a\u014b\u0005n\u0000\u0000\u014b\u014c\u0005"+
"s\u0000\u0000\u014c\u014d\u0005t\u0000\u0000\u014d\u0014\u0001\u0000\u0000"+
"\u0000\u014e\u014f\u0005c\u0000\u0000\u014f\u0150\u0005o\u0000\u0000\u0150"+
"\u0151\u0005n\u0000\u0000\u0151\u0152\u0005t\u0000\u0000\u0152\u0153\u0005"+
"i\u0000\u0000\u0153\u0154\u0005n\u0000\u0000\u0154\u0155\u0005u\u0000"+
"\u0000\u0155\u0156\u0005e\u0000\u0000\u0156\u0016\u0001\u0000\u0000\u0000"+
"\u0157\u0158\u0005d\u0000\u0000\u0158\u0159\u0005e\u0000\u0000\u0159\u015a"+
"\u0005f\u0000\u0000\u015a\u015b\u0005a\u0000\u0000\u015b\u015c\u0005u"+
"\u0000\u0000\u015c\u015d\u0005l\u0000\u0000\u015d\u015e\u0005t\u0000\u0000"+
"\u015e\u0018\u0001\u0000\u0000\u0000\u015f\u0160\u0005d\u0000\u0000\u0160"+
"\u0161\u0005o\u0000\u0000\u0161\u001a\u0001\u0000\u0000\u0000\u0162\u0163"+
"\u0005d\u0000\u0000\u0163\u0164\u0005o\u0000\u0000\u0164\u0165\u0005u"+
"\u0000\u0000\u0165\u0166\u0005b\u0000\u0000\u0166\u0167\u0005l\u0000\u0000"+
"\u0167\u0168\u0005e\u0000\u0000\u0168\u001c\u0001\u0000\u0000\u0000\u0169"+
"\u016a\u0005e\u0000\u0000\u016a\u016b\u0005l\u0000\u0000\u016b\u016c\u0005"+
"s\u0000\u0000\u016c\u016d\u0005e\u0000\u0000\u016d\u001e\u0001\u0000\u0000"+
"\u0000\u016e\u016f\u0005e\u0000\u0000\u016f\u0170\u0005n\u0000\u0000\u0170"+
"\u0171\u0005u\u0000\u0000\u0171\u0172\u0005m\u0000\u0000\u0172 \u0001"+
"\u0000\u0000\u0000\u0173\u0174\u0005e\u0000\u0000\u0174\u0175\u0005x\u0000"+
"\u0000\u0175\u0176\u0005t\u0000\u0000\u0176\u0177\u0005e\u0000\u0000\u0177"+
"\u0178\u0005n\u0000\u0000\u0178\u0179\u0005d\u0000\u0000\u0179\u017a\u0005"+
"s\u0000\u0000\u017a\"\u0001\u0000\u0000\u0000\u017b\u017c\u0005f\u0000"+
"\u0000\u017c\u017d\u0005i\u0000\u0000\u017d\u017e\u0005n\u0000\u0000\u017e"+
"\u017f\u0005a\u0000\u0000\u017f\u0180\u0005l\u0000\u0000\u0180$\u0001"+
"\u0000\u0000\u0000\u0181\u0182\u0005f\u0000\u0000\u0182\u0183\u0005i\u0000"+
"\u0000\u0183\u0184\u0005n\u0000\u0000\u0184\u0185\u0005a\u0000\u0000\u0185"+
"\u0186\u0005l\u0000\u0000\u0186\u0187\u0005l\u0000\u0000\u0187\u0188\u0005"+
"y\u0000\u0000\u0188&\u0001\u0000\u0000\u0000\u0189\u018a\u0005f\u0000"+
"\u0000\u018a\u018b\u0005l\u0000\u0000\u018b\u018c\u0005o\u0000\u0000\u018c"+
"\u018d\u0005a\u0000\u0000\u018d\u018e\u0005t\u0000\u0000\u018e(\u0001"+
"\u0000\u0000\u0000\u018f\u0190\u0005f\u0000\u0000\u0190\u0191\u0005o\u0000"+
"\u0000\u0191\u0192\u0005r\u0000\u0000\u0192*\u0001\u0000\u0000\u0000\u0193"+
"\u0194\u0005i\u0000\u0000\u0194\u0195\u0005f\u0000\u0000\u0195,\u0001"+
"\u0000\u0000\u0000\u0196\u0197\u0005g\u0000\u0000\u0197\u0198\u0005o\u0000"+
"\u0000\u0198\u0199\u0005t\u0000\u0000\u0199\u019a\u0005o\u0000\u0000\u019a"+
".\u0001\u0000\u0000\u0000\u019b\u019c\u0005i\u0000\u0000\u019c\u019d\u0005"+
"m\u0000\u0000\u019d\u019e\u0005p\u0000\u0000\u019e\u019f\u0005l\u0000"+
"\u0000\u019f\u01a0\u0005e\u0000\u0000\u01a0\u01a1\u0005m\u0000\u0000\u01a1"+
"\u01a2\u0005e\u0000\u0000\u01a2\u01a3\u0005n\u0000\u0000\u01a3\u01a4\u0005"+
"t\u0000\u0000\u01a4\u01a5\u0005s\u0000\u0000\u01a50\u0001\u0000\u0000"+
"\u0000\u01a6\u01a7\u0005i\u0000\u0000\u01a7\u01a8\u0005m\u0000\u0000\u01a8"+
"\u01a9\u0005p\u0000\u0000\u01a9\u01aa\u0005o\u0000\u0000\u01aa\u01ab\u0005"+
"r\u0000\u0000\u01ab\u01ac\u0005t\u0000\u0000\u01ac2\u0001\u0000\u0000"+
"\u0000\u01ad\u01ae\u0005i\u0000\u0000\u01ae\u01af\u0005n\u0000\u0000\u01af"+
"\u01b0\u0005s\u0000\u0000\u01b0\u01b1\u0005t\u0000\u0000\u01b1\u01b2\u0005"+
"a\u0000\u0000\u01b2\u01b3\u0005n\u0000\u0000\u01b3\u01b4\u0005c\u0000"+
"\u0000\u01b4\u01b5\u0005e\u0000\u0000\u01b5\u01b6\u0005o\u0000\u0000\u01b6"+
"\u01b7\u0005f\u0000\u0000\u01b74\u0001\u0000\u0000\u0000\u01b8\u01b9\u0005"+
"i\u0000\u0000\u01b9\u01ba\u0005n\u0000\u0000\u01ba\u01bb\u0005t\u0000"+
"\u0000\u01bb6\u0001\u0000\u0000\u0000\u01bc\u01bd\u0005i\u0000\u0000\u01bd"+
"\u01be\u0005n\u0000\u0000\u01be\u01bf\u0005t\u0000\u0000\u01bf\u01c0\u0005"+
"e\u0000\u0000\u01c0\u01c1\u0005r\u0000\u0000\u01c1\u01c2\u0005f\u0000"+
"\u0000\u01c2\u01c3\u0005a\u0000\u0000\u01c3\u01c4\u0005c\u0000\u0000\u01c4"+
"\u01c5\u0005e\u0000\u0000\u01c58\u0001\u0000\u0000\u0000\u01c6\u01c7\u0005"+
"l\u0000\u0000\u01c7\u01c8\u0005o\u0000\u0000\u01c8\u01c9\u0005n\u0000"+
"\u0000\u01c9\u01ca\u0005g\u0000\u0000\u01ca:\u0001\u0000\u0000\u0000\u01cb"+
"\u01cc\u0005n\u0000\u0000\u01cc\u01cd\u0005a\u0000\u0000\u01cd\u01ce\u0005"+
"t\u0000\u0000\u01ce\u01cf\u0005i\u0000\u0000\u01cf\u01d0\u0005v\u0000"+
"\u0000\u01d0\u01d1\u0005e\u0000\u0000\u01d1<\u0001\u0000\u0000\u0000\u01d2"+
"\u01d3\u0005n\u0000\u0000\u01d3\u01d4\u0005e\u0000\u0000\u01d4\u01d5\u0005"+
"w\u0000\u0000\u01d5>\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005p\u0000"+
"\u0000\u01d7\u01d8\u0005a\u0000\u0000\u01d8\u01d9\u0005c\u0000\u0000\u01d9"+
"\u01da\u0005k\u0000\u0000\u01da\u01db\u0005a\u0000\u0000\u01db\u01dc\u0005"+
"g\u0000\u0000\u01dc\u01dd\u0005e\u0000\u0000\u01dd@\u0001\u0000\u0000"+
"\u0000\u01de\u01df\u0005p\u0000\u0000\u01df\u01e0\u0005r\u0000\u0000\u01e0"+
"\u01e1\u0005i\u0000\u0000\u01e1\u01e2\u0005v\u0000\u0000\u01e2\u01e3\u0005"+
"a\u0000\u0000\u01e3\u01e4\u0005t\u0000\u0000\u01e4\u01e5\u0005e\u0000"+
"\u0000\u01e5B\u0001\u0000\u0000\u0000\u01e6\u01e7\u0005p\u0000\u0000\u01e7"+
"\u01e8\u0005r\u0000\u0000\u01e8\u01e9\u0005o\u0000\u0000\u01e9\u01ea\u0005"+
"t\u0000\u0000\u01ea\u01eb\u0005e\u0000\u0000\u01eb\u01ec\u0005c\u0000"+
"\u0000\u01ec\u01ed\u0005t\u0000\u0000\u01ed\u01ee\u0005e\u0000\u0000\u01ee"+
"\u01ef\u0005d\u0000\u0000\u01efD\u0001\u0000\u0000\u0000\u01f0\u01f1\u0005"+
"p\u0000\u0000\u01f1\u01f2\u0005u\u0000\u0000\u01f2\u01f3\u0005b\u0000"+
"\u0000\u01f3\u01f4\u0005l\u0000\u0000\u01f4\u01f5\u0005i\u0000\u0000\u01f5"+
"\u01f6\u0005c\u0000\u0000\u01f6F\u0001\u0000\u0000\u0000\u01f7\u01f8\u0005"+
"r\u0000\u0000\u01f8\u01f9\u0005e\u0000\u0000\u01f9\u01fa\u0005t\u0000"+
"\u0000\u01fa\u01fb\u0005u\u0000\u0000\u01fb\u01fc\u0005r\u0000\u0000\u01fc"+
"\u01fd\u0005n\u0000\u0000\u01fdH\u0001\u0000\u0000\u0000\u01fe\u01ff\u0005"+
"s\u0000\u0000\u01ff\u0200\u0005h\u0000\u0000\u0200\u0201\u0005o\u0000"+
"\u0000\u0201\u0202\u0005r\u0000\u0000\u0202\u0203\u0005t\u0000\u0000\u0203"+
"J\u0001\u0000\u0000\u0000\u0204\u0205\u0005s\u0000\u0000\u0205\u0206\u0005"+
"t\u0000\u0000\u0206\u0207\u0005a\u0000\u0000\u0207\u0208\u0005t\u0000"+
"\u0000\u0208\u0209\u0005i\u0000\u0000\u0209\u020a\u0005c\u0000\u0000\u020a"+
"L\u0001\u0000\u0000\u0000\u020b\u020c\u0005s\u0000\u0000\u020c\u020d\u0005"+
"t\u0000\u0000\u020d\u020e\u0005r\u0000\u0000\u020e\u020f\u0005i\u0000"+
"\u0000\u020f\u0210\u0005c\u0000\u0000\u0210\u0211\u0005t\u0000\u0000\u0211"+
"\u0212\u0005f\u0000\u0000\u0212\u0213\u0005p\u0000\u0000\u0213N\u0001"+
"\u0000\u0000\u0000\u0214\u0215\u0005s\u0000\u0000\u0215\u0216\u0005u\u0000"+
"\u0000\u0216\u0217\u0005p\u0000\u0000\u0217\u0218\u0005e\u0000\u0000\u0218"+
"\u0219\u0005r\u0000\u0000\u0219P\u0001\u0000\u0000\u0000\u021a\u021b\u0005"+
"s\u0000\u0000\u021b\u021c\u0005w\u0000\u0000\u021c\u021d\u0005i\u0000"+
"\u0000\u021d\u021e\u0005t\u0000\u0000\u021e\u021f\u0005c\u0000\u0000\u021f"+
"\u0220\u0005h\u0000\u0000\u0220R\u0001\u0000\u0000\u0000\u0221\u0222\u0005"+
"s\u0000\u0000\u0222\u0223\u0005y\u0000\u0000\u0223\u0224\u0005n\u0000"+
"\u0000\u0224\u0225\u0005c\u0000\u0000\u0225\u0226\u0005h\u0000\u0000\u0226"+
"\u0227\u0005r\u0000\u0000\u0227\u0228\u0005o\u0000\u0000\u0228\u0229\u0005"+
"n\u0000\u0000\u0229\u022a\u0005i\u0000\u0000\u022a\u022b\u0005z\u0000"+
"\u0000\u022b\u022c\u0005e\u0000\u0000\u022c\u022d\u0005d\u0000\u0000\u022d"+
"T\u0001\u0000\u0000\u0000\u022e\u022f\u0005t\u0000\u0000\u022f\u0230\u0005"+
"h\u0000\u0000\u0230\u0231\u0005i\u0000\u0000\u0231\u0232\u0005s\u0000"+
"\u0000\u0232V\u0001\u0000\u0000\u0000\u0233\u0234\u0005t\u0000\u0000\u0234"+
"\u0235\u0005h\u0000\u0000\u0235\u0236\u0005r\u0000\u0000\u0236\u0237\u0005"+
"o\u0000\u0000\u0237\u0238\u0005w\u0000\u0000\u0238X\u0001\u0000\u0000"+
"\u0000\u0239\u023a\u0005t\u0000\u0000\u023a\u023b\u0005h\u0000\u0000\u023b"+
"\u023c\u0005r\u0000\u0000\u023c\u023d\u0005o\u0000\u0000\u023d\u023e\u0005"+
"w\u0000\u0000\u023e\u023f\u0005s\u0000\u0000\u023fZ\u0001\u0000\u0000"+
"\u0000\u0240\u0241\u0005t\u0000\u0000\u0241\u0242\u0005r\u0000\u0000\u0242"+
"\u0243\u0005a\u0000\u0000\u0243\u0244\u0005n\u0000\u0000\u0244\u0245\u0005"+
"s\u0000\u0000\u0245\u0246\u0005i\u0000\u0000\u0246\u0247\u0005e\u0000"+
"\u0000\u0247\u0248\u0005n\u0000\u0000\u0248\u0249\u0005t\u0000\u0000\u0249"+
"\\\u0001\u0000\u0000\u0000\u024a\u024b\u0005t\u0000\u0000\u024b\u024c"+
"\u0005r\u0000\u0000\u024c\u024d\u0005y\u0000\u0000\u024d^\u0001\u0000"+
"\u0000\u0000\u024e\u024f\u0005v\u0000\u0000\u024f\u0250\u0005o\u0000\u0000"+
"\u0250\u0251\u0005i\u0000\u0000\u0251\u0252\u0005d\u0000\u0000\u0252`"+
"\u0001\u0000\u0000\u0000\u0253\u0254\u0005v\u0000\u0000\u0254\u0255\u0005"+
"o\u0000\u0000\u0255\u0256\u0005l\u0000\u0000\u0256\u0257\u0005a\u0000"+
"\u0000\u0257\u0258\u0005t\u0000\u0000\u0258\u0259\u0005i\u0000\u0000\u0259"+
"\u025a\u0005l\u0000\u0000\u025a\u025b\u0005e\u0000\u0000\u025bb\u0001"+
"\u0000\u0000\u0000\u025c\u025d\u0005w\u0000\u0000\u025d\u025e\u0005h\u0000"+
"\u0000\u025e\u025f\u0005i\u0000\u0000\u025f\u0260\u0005l\u0000\u0000\u0260"+
"\u0261\u0005e\u0000\u0000\u0261d\u0001\u0000\u0000\u0000\u0262\u0263\u0005"+
"m\u0000\u0000\u0263\u0264\u0005o\u0000\u0000\u0264\u0265\u0005d\u0000"+
"\u0000\u0265\u0266\u0005u\u0000\u0000\u0266\u0267\u0005l\u0000\u0000\u0267"+
"\u0268\u0005e\u0000\u0000\u0268f\u0001\u0000\u0000\u0000\u0269\u026a\u0005"+
"o\u0000\u0000\u026a\u026b\u0005p\u0000\u0000\u026b\u026c\u0005e\u0000"+
"\u0000\u026c\u026d\u0005n\u0000\u0000\u026dh\u0001\u0000\u0000\u0000\u026e"+
"\u026f\u0005r\u0000\u0000\u026f\u0270\u0005e\u0000\u0000\u0270\u0271\u0005"+
"q\u0000\u0000\u0271\u0272\u0005u\u0000\u0000\u0272\u0273\u0005i\u0000"+
"\u0000\u0273\u0274\u0005r\u0000\u0000\u0274\u0275\u0005e\u0000\u0000\u0275"+
"\u0276\u0005s\u0000\u0000\u0276j\u0001\u0000\u0000\u0000\u0277\u0278\u0005"+
"e\u0000\u0000\u0278\u0279\u0005x\u0000\u0000\u0279\u027a\u0005p\u0000"+
"\u0000\u027a\u027b\u0005o\u0000\u0000\u027b\u027c\u0005r\u0000\u0000\u027c"+
"\u027d\u0005t\u0000\u0000\u027d\u027e\u0005s\u0000\u0000\u027el\u0001"+
"\u0000\u0000\u0000\u027f\u0280\u0005o\u0000\u0000\u0280\u0281\u0005p\u0000"+
"\u0000\u0281\u0282\u0005e\u0000\u0000\u0282\u0283\u0005n\u0000\u0000\u0283"+
"\u0284\u0005s\u0000\u0000\u0284n\u0001\u0000\u0000\u0000\u0285\u0286\u0005"+
"t\u0000\u0000\u0286\u0287\u0005o\u0000\u0000\u0287p\u0001\u0000\u0000"+
"\u0000\u0288\u0289\u0005u\u0000\u0000\u0289\u028a\u0005s\u0000\u0000\u028a"+
"\u028b\u0005e\u0000\u0000\u028b\u028c\u0005s\u0000\u0000\u028cr\u0001"+
"\u0000\u0000\u0000\u028d\u028e\u0005p\u0000\u0000\u028e\u028f\u0005r\u0000"+
"\u0000\u028f\u0290\u0005o\u0000\u0000\u0290\u0291\u0005v\u0000\u0000\u0291"+
"\u0292\u0005i\u0000\u0000\u0292\u0293\u0005d\u0000\u0000\u0293\u0294\u0005"+
"e\u0000\u0000\u0294\u0295\u0005s\u0000\u0000\u0295t\u0001\u0000\u0000"+
"\u0000\u0296\u0297\u0005w\u0000\u0000\u0297\u0298\u0005i\u0000\u0000\u0298"+
"\u0299\u0005t\u0000\u0000\u0299\u029a\u0005h\u0000\u0000\u029av\u0001"+
"\u0000\u0000\u0000\u029b\u029c\u0005t\u0000\u0000\u029c\u029d\u0005r\u0000"+
"\u0000\u029d\u029e\u0005a\u0000\u0000\u029e\u029f\u0005n\u0000\u0000\u029f"+
"\u02a0\u0005s\u0000\u0000\u02a0\u02a1\u0005i\u0000\u0000\u02a1\u02a2\u0005"+
"t\u0000\u0000\u02a2\u02a3\u0005i\u0000\u0000\u02a3\u02a4\u0005v\u0000"+
"\u0000\u02a4\u02a5\u0005e\u0000\u0000\u02a5x\u0001\u0000\u0000\u0000\u02a6"+
"\u02a7\u0005v\u0000\u0000\u02a7\u02a8\u0005a\u0000\u0000\u02a8\u02a9\u0005"+
"r\u0000\u0000\u02a9z\u0001\u0000\u0000\u0000\u02aa\u02ab\u0005y\u0000"+
"\u0000\u02ab\u02ac\u0005i\u0000\u0000\u02ac\u02ad\u0005e\u0000\u0000\u02ad"+
"\u02ae\u0005l\u0000\u0000\u02ae\u02af\u0005d\u0000\u0000\u02af|\u0001"+
"\u0000\u0000\u0000\u02b0\u02b1\u0005r\u0000\u0000\u02b1\u02b2\u0005e\u0000"+
"\u0000\u02b2\u02b3\u0005c\u0000\u0000\u02b3\u02b4\u0005o\u0000\u0000\u02b4"+
"\u02b5\u0005r\u0000\u0000\u02b5\u02b6\u0005d\u0000\u0000\u02b6~\u0001"+
"\u0000\u0000\u0000\u02b7\u02b8\u0005s\u0000\u0000\u02b8\u02b9\u0005e\u0000"+
"\u0000\u02b9\u02ba\u0005a\u0000\u0000\u02ba\u02bb\u0005l\u0000\u0000\u02bb"+
"\u02bc\u0005e\u0000\u0000\u02bc\u02bd\u0005d\u0000\u0000\u02bd\u0080\u0001"+
"\u0000\u0000\u0000\u02be\u02bf\u0005p\u0000\u0000\u02bf\u02c0\u0005e\u0000"+
"\u0000\u02c0\u02c1\u0005r\u0000\u0000\u02c1\u02c2\u0005m\u0000\u0000\u02c2"+
"\u02c3\u0005i\u0000\u0000\u02c3\u02c4\u0005t\u0000\u0000\u02c4\u02c5\u0005"+
"s\u0000\u0000\u02c5\u0082\u0001\u0000\u0000\u0000\u02c6\u02c7\u0005n\u0000"+
"\u0000\u02c7\u02c8\u0005o\u0000\u0000\u02c8\u02c9\u0005n\u0000\u0000\u02c9"+
"\u02ca\u0005-\u0000\u0000\u02ca\u02cb\u0005s\u0000\u0000\u02cb\u02cc\u0005"+
"e\u0000\u0000\u02cc\u02cd\u0005a\u0000\u0000\u02cd\u02ce\u0005l\u0000"+
"\u0000\u02ce\u02cf\u0005e\u0000\u0000\u02cf\u02d0\u0005d\u0000\u0000\u02d0"+
"\u0084\u0001\u0000\u0000\u0000\u02d1\u02df\u00050\u0000\u0000\u02d2\u02dc"+
"\u0007\u0000\u0000\u0000\u02d3\u02d5\u0003\u0109\u0084\u0000\u02d4\u02d3"+
"\u0001\u0000\u0000\u0000\u02d4\u02d5\u0001\u0000\u0000\u0000\u02d5\u02dd"+
"\u0001\u0000\u0000\u0000\u02d6\u02d8\u0005_\u0000\u0000\u02d7\u02d6\u0001"+
"\u0000\u0000\u0000\u02d8\u02d9\u0001\u0000\u0000\u0000\u02d9\u02d7\u0001"+
"\u0000\u0000\u0000\u02d9\u02da\u0001\u0000\u0000\u0000\u02da\u02db\u0001"+
"\u0000\u0000\u0000\u02db\u02dd\u0003\u0109\u0084\u0000\u02dc\u02d4\u0001"+
"\u0000\u0000\u0000\u02dc\u02d7\u0001\u0000\u0000\u0000\u02dd\u02df\u0001"+
"\u0000\u0000\u0000\u02de\u02d1\u0001\u0000\u0000\u0000\u02de\u02d2\u0001"+
"\u0000\u0000\u0000\u02df\u02e1\u0001\u0000\u0000\u0000\u02e0\u02e2\u0007"+
"\u0001\u0000\u0000\u02e1\u02e0\u0001\u0000\u0000\u0000\u02e1\u02e2\u0001"+
"\u0000\u0000\u0000\u02e2\u0086\u0001\u0000\u0000\u0000\u02e3\u02e4\u0005"+
"0\u0000\u0000\u02e4\u02e5\u0007\u0002\u0000\u0000\u02e5\u02ed\u0007\u0003"+
"\u0000\u0000\u02e6\u02e8\u0007\u0004\u0000\u0000\u02e7\u02e6\u0001\u0000"+
"\u0000\u0000\u02e8\u02eb\u0001\u0000\u0000\u0000\u02e9\u02e7\u0001\u0000"+
"\u0000\u0000\u02e9\u02ea\u0001\u0000\u0000\u0000\u02ea\u02ec\u0001\u0000"+
"\u0000\u0000\u02eb\u02e9\u0001\u0000\u0000\u0000\u02ec\u02ee\u0007\u0003"+
"\u0000\u0000\u02ed\u02e9\u0001\u0000\u0000\u0000\u02ed\u02ee\u0001\u0000"+
"\u0000\u0000\u02ee\u02f0\u0001\u0000\u0000\u0000\u02ef\u02f1\u0007\u0001"+
"\u0000\u0000\u02f0\u02ef\u0001\u0000\u0000\u0000\u02f0\u02f1\u0001\u0000"+
"\u0000\u0000\u02f1\u0088\u0001\u0000\u0000\u0000\u02f2\u02f6\u00050\u0000"+
"\u0000\u02f3\u02f5\u0005_\u0000\u0000\u02f4\u02f3\u0001\u0000\u0000\u0000"+
"\u02f5\u02f8\u0001\u0000\u0000\u0000\u02f6\u02f4\u0001\u0000\u0000\u0000"+
"\u02f6\u02f7\u0001\u0000\u0000\u0000\u02f7\u02f9\u0001\u0000\u0000\u0000"+
"\u02f8\u02f6\u0001\u0000\u0000\u0000\u02f9\u0301\u0007\u0005\u0000\u0000"+
"\u02fa\u02fc\u0007\u0006\u0000\u0000\u02fb\u02fa\u0001\u0000\u0000\u0000"+
"\u02fc\u02ff\u0001\u0000\u0000\u0000\u02fd\u02fb\u0001\u0000\u0000\u0000"+
"\u02fd\u02fe\u0001\u0000\u0000\u0000\u02fe\u0300\u0001\u0000\u0000\u0000"+
"\u02ff\u02fd\u0001\u0000\u0000\u0000\u0300\u0302\u0007\u0005\u0000\u0000"+
"\u0301\u02fd\u0001\u0000\u0000\u0000\u0301\u0302\u0001\u0000\u0000\u0000"+
"\u0302\u0304\u0001\u0000\u0000\u0000\u0303\u0305\u0007\u0001\u0000\u0000"+
"\u0304\u0303\u0001\u0000\u0000\u0000\u0304\u0305\u0001\u0000\u0000\u0000"+
"\u0305\u008a\u0001\u0000\u0000\u0000\u0306\u0307\u00050\u0000\u0000\u0307"+
"\u0308\u0007\u0007\u0000\u0000\u0308\u0310\u0007\b\u0000\u0000\u0309\u030b"+
"\u0007\t\u0000\u0000\u030a\u0309\u0001\u0000\u0000\u0000\u030b\u030e\u0001"+
"\u0000\u0000\u0000\u030c\u030a\u0001\u0000\u0000\u0000\u030c\u030d\u0001"+
"\u0000\u0000\u0000\u030d\u030f\u0001\u0000\u0000\u0000\u030e\u030c\u0001"+
"\u0000\u0000\u0000\u030f\u0311\u0007\b\u0000\u0000\u0310\u030c\u0001\u0000"+
"\u0000\u0000\u0310\u0311\u0001\u0000\u0000\u0000\u0311\u0313\u0001\u0000"+
"\u0000\u0000\u0312\u0314\u0007\u0001\u0000\u0000\u0313\u0312\u0001\u0000"+
"\u0000\u0000\u0313\u0314\u0001\u0000\u0000\u0000\u0314\u008c\u0001\u0000"+
"\u0000\u0000\u0315\u0316\u0003\u0109\u0084\u0000\u0316\u0318\u0005.\u0000"+
"\u0000\u0317\u0319\u0003\u0109\u0084\u0000\u0318\u0317\u0001\u0000\u0000"+
"\u0000\u0318\u0319\u0001\u0000\u0000\u0000\u0319\u031d\u0001\u0000\u0000"+
"\u0000\u031a\u031b\u0005.\u0000\u0000\u031b\u031d\u0003\u0109\u0084\u0000"+
"\u031c\u0315\u0001\u0000\u0000\u0000\u031c\u031a\u0001\u0000\u0000\u0000"+
"\u031d\u031f\u0001\u0000\u0000\u0000\u031e\u0320\u0003\u0101\u0080\u0000"+
"\u031f\u031e\u0001\u0000\u0000\u0000\u031f\u0320\u0001\u0000\u0000\u0000"+
"\u0320\u0322\u0001\u0000\u0000\u0000\u0321\u0323\u0007\n\u0000\u0000\u0322"+
"\u0321\u0001\u0000\u0000\u0000\u0322\u0323\u0001\u0000\u0000\u0000\u0323"+
"\u032d\u0001\u0000\u0000\u0000\u0324\u032a\u0003\u0109\u0084\u0000\u0325"+
"\u0327\u0003\u0101\u0080\u0000\u0326\u0328\u0007\n\u0000\u0000\u0327\u0326"+
"\u0001\u0000\u0000\u0000\u0327\u0328\u0001\u0000\u0000\u0000\u0328\u032b"+
"\u0001\u0000\u0000\u0000\u0329\u032b\u0007\n\u0000\u0000\u032a\u0325\u0001"+
"\u0000\u0000\u0000\u032a\u0329\u0001\u0000\u0000\u0000\u032b\u032d\u0001"+
"\u0000\u0000\u0000\u032c\u031c\u0001\u0000\u0000\u0000\u032c\u0324\u0001"+
"\u0000\u0000\u0000\u032d\u008e\u0001\u0000\u0000\u0000\u032e\u032f\u0005"+
"0\u0000\u0000\u032f\u0339\u0007\u0002\u0000\u0000\u0330\u0332\u0003\u0105"+
"\u0082\u0000\u0331\u0333\u0005.\u0000\u0000\u0332\u0331\u0001\u0000\u0000"+
"\u0000\u0332\u0333\u0001\u0000\u0000\u0000\u0333\u033a\u0001\u0000\u0000"+
"\u0000\u0334\u0336\u0003\u0105\u0082\u0000\u0335\u0334\u0001\u0000\u0000"+
"\u0000\u0335\u0336\u0001\u0000\u0000\u0000\u0336\u0337\u0001\u0000\u0000"+
"\u0000\u0337\u0338\u0005.\u0000\u0000\u0338\u033a\u0003\u0105\u0082\u0000"+
"\u0339\u0330\u0001\u0000\u0000\u0000\u0339\u0335\u0001\u0000\u0000\u0000"+
"\u033a\u033b\u0001\u0000\u0000\u0000\u033b\u033d\u0007\u000b\u0000\u0000"+
"\u033c\u033e\u0007\f\u0000\u0000\u033d\u033c\u0001\u0000\u0000\u0000\u033d"+
"\u033e\u0001\u0000\u0000\u0000\u033e\u033f\u0001\u0000\u0000\u0000\u033f"+
"\u0341\u0003\u0109\u0084\u0000\u0340\u0342\u0007\n\u0000\u0000\u0341\u0340"+
"\u0001\u0000\u0000\u0000\u0341\u0342\u0001\u0000\u0000\u0000\u0342\u0090"+
"\u0001\u0000\u0000\u0000\u0343\u0344\u0005t\u0000\u0000\u0344\u0345\u0005"+
"r\u0000\u0000\u0345\u0346\u0005u\u0000\u0000\u0346\u034d\u0005e\u0000"+
"\u0000\u0347\u0348\u0005f\u0000\u0000\u0348\u0349\u0005a\u0000\u0000\u0349"+
"\u034a\u0005l\u0000\u0000\u034a\u034b\u0005s\u0000\u0000\u034b\u034d\u0005"+
"e\u0000\u0000\u034c\u0343\u0001\u0000\u0000\u0000\u034c\u0347\u0001\u0000"+
"\u0000\u0000\u034d\u0092\u0001\u0000\u0000\u0000\u034e\u0351\u0005\'\u0000"+
"\u0000\u034f\u0352\b\r\u0000\u0000\u0350\u0352\u0003\u0103\u0081\u0000"+
"\u0351\u034f\u0001\u0000\u0000\u0000\u0351\u0350\u0001\u0000\u0000\u0000"+
"\u0352\u0353\u0001\u0000\u0000\u0000\u0353\u0354\u0005\'\u0000\u0000\u0354"+
"\u0094\u0001\u0000\u0000\u0000\u0355\u035a\u0005\"\u0000\u0000\u0356\u0359"+
"\b\u000e\u0000\u0000\u0357\u0359\u0003\u0103\u0081\u0000\u0358\u0356\u0001"+
"\u0000\u0000\u0000\u0358\u0357\u0001\u0000\u0000\u0000\u0359\u035c\u0001"+
"\u0000\u0000\u0000\u035a\u0358\u0001\u0000\u0000\u0000\u035a\u035b\u0001"+
"\u0000\u0000\u0000\u035b\u035d\u0001\u0000\u0000\u0000\u035c\u035a\u0001"+
"\u0000\u0000\u0000\u035d\u035e\u0005\"\u0000\u0000\u035e\u0096\u0001\u0000"+
"\u0000\u0000\u035f\u0360\u0005\"\u0000\u0000\u0360\u0361\u0005\"\u0000"+
"\u0000\u0361\u0362\u0005\"\u0000\u0000\u0362\u0366\u0001\u0000\u0000\u0000"+
"\u0363\u0365\u0007\u000f\u0000\u0000\u0364\u0363\u0001\u0000\u0000\u0000"+
"\u0365\u0368\u0001\u0000\u0000\u0000\u0366\u0364\u0001\u0000\u0000\u0000"+
"\u0366\u0367\u0001\u0000\u0000\u0000\u0367\u0369\u0001\u0000\u0000\u0000"+
"\u0368\u0366\u0001\u0000\u0000\u0000\u0369\u036e\u0007\u0010\u0000\u0000"+
"\u036a\u036d\t\u0000\u0000\u0000\u036b\u036d\u0003\u0103\u0081\u0000\u036c"+
"\u036a\u0001\u0000\u0000\u0000\u036c\u036b\u0001\u0000\u0000\u0000\u036d"+
"\u0370\u0001\u0000\u0000\u0000\u036e\u036f\u0001\u0000\u0000\u0000\u036e"+
"\u036c\u0001\u0000\u0000\u0000\u036f\u0371\u0001\u0000\u0000\u0000\u0370"+
"\u036e\u0001\u0000\u0000\u0000\u0371\u0372\u0005\"\u0000\u0000\u0372\u0373"+
"\u0005\"\u0000\u0000\u0373\u0374\u0005\"\u0000\u0000\u0374\u0098\u0001"+
"\u0000\u0000\u0000\u0375\u0376\u0005n\u0000\u0000\u0376\u0377\u0005u\u0000"+
"\u0000\u0377\u0378\u0005l\u0000\u0000\u0378\u0379\u0005l\u0000\u0000\u0379"+
"\u009a\u0001\u0000\u0000\u0000\u037a\u037b\u0005(\u0000\u0000\u037b\u009c"+
"\u0001\u0000\u0000\u0000\u037c\u037d\u0005)\u0000\u0000\u037d\u009e\u0001"+
"\u0000\u0000\u0000\u037e\u037f\u0005{\u0000\u0000\u037f\u00a0\u0001\u0000"+
"\u0000\u0000\u0380\u0381\u0005}\u0000\u0000\u0381\u00a2\u0001\u0000\u0000"+
"\u0000\u0382\u0383\u0005[\u0000\u0000\u0383\u00a4\u0001\u0000\u0000\u0000"+
"\u0384\u0385\u0005]\u0000\u0000\u0385\u00a6\u0001\u0000\u0000\u0000\u0386"+
"\u0387\u0005;\u0000\u0000\u0387\u00a8\u0001\u0000\u0000\u0000\u0388\u0389"+
"\u0005,\u0000\u0000\u0389\u00aa\u0001\u0000\u0000\u0000\u038a\u038b\u0005"+
".\u0000\u0000\u038b\u00ac\u0001\u0000\u0000\u0000\u038c\u038d\u0005=\u0000"+
"\u0000\u038d\u00ae\u0001\u0000\u0000\u0000\u038e\u038f\u0005>\u0000\u0000"+
"\u038f\u00b0\u0001\u0000\u0000\u0000\u0390\u0391\u0005<\u0000\u0000\u0391"+
"\u00b2\u0001\u0000\u0000\u0000\u0392\u0393\u0005!\u0000\u0000\u0393\u00b4"+
"\u0001\u0000\u0000\u0000\u0394\u0395\u0005~\u0000\u0000\u0395\u00b6\u0001"+
"\u0000\u0000\u0000\u0396\u0397\u0005?\u0000\u0000\u0397\u00b8\u0001\u0000"+
"\u0000\u0000\u0398\u0399\u0005:\u0000\u0000\u0399\u00ba\u0001\u0000\u0000"+
"\u0000\u039a\u039b\u0005=\u0000\u0000\u039b\u039c\u0005=\u0000\u0000\u039c"+
"\u00bc\u0001\u0000\u0000\u0000\u039d\u039e\u0005<\u0000\u0000\u039e\u039f"+
"\u0005=\u0000\u0000\u039f\u00be\u0001\u0000\u0000\u0000\u03a0\u03a1\u0005"+
">\u0000\u0000\u03a1\u03a2\u0005=\u0000\u0000\u03a2\u00c0\u0001\u0000\u0000"+
"\u0000\u03a3\u03a4\u0005!\u0000\u0000\u03a4\u03a5\u0005=\u0000\u0000\u03a5"+
"\u00c2\u0001\u0000\u0000\u0000\u03a6\u03a7\u0005&\u0000\u0000\u03a7\u03a8"+
"\u0005&\u0000\u0000\u03a8\u00c4\u0001\u0000\u0000\u0000\u03a9\u03aa\u0005"+
"|\u0000\u0000\u03aa\u03ab\u0005|\u0000\u0000\u03ab\u00c6\u0001\u0000\u0000"+
"\u0000\u03ac\u03ad\u0005+\u0000\u0000\u03ad\u03ae\u0005+\u0000\u0000\u03ae"+
"\u00c8\u0001\u0000\u0000\u0000\u03af\u03b0\u0005-\u0000\u0000\u03b0\u03b1"+
"\u0005-\u0000\u0000\u03b1\u00ca\u0001\u0000\u0000\u0000\u03b2\u03b3\u0005"+
"+\u0000\u0000\u03b3\u00cc\u0001\u0000\u0000\u0000\u03b4\u03b5\u0005-\u0000"+
"\u0000\u03b5\u00ce\u0001\u0000\u0000\u0000\u03b6\u03b7\u0005*\u0000\u0000"+
"\u03b7\u00d0\u0001\u0000\u0000\u0000\u03b8\u03b9\u0005/\u0000\u0000\u03b9"+
"\u00d2\u0001\u0000\u0000\u0000\u03ba\u03bb\u0005&\u0000\u0000\u03bb\u00d4"+
"\u0001\u0000\u0000\u0000\u03bc\u03bd\u0005|\u0000\u0000\u03bd\u00d6\u0001"+
"\u0000\u0000\u0000\u03be\u03bf\u0005^\u0000\u0000\u03bf\u00d8\u0001\u0000"+
"\u0000\u0000\u03c0\u03c1\u0005%\u0000\u0000\u03c1\u00da\u0001\u0000\u0000"+
"\u0000\u03c2\u03c3\u0005+\u0000\u0000\u03c3\u03c4\u0005=\u0000\u0000\u03c4"+
"\u00dc\u0001\u0000\u0000\u0000\u03c5\u03c6\u0005-\u0000\u0000\u03c6\u03c7"+
"\u0005=\u0000\u0000\u03c7\u00de\u0001\u0000\u0000\u0000\u03c8\u03c9\u0005"+
"*\u0000\u0000\u03c9\u03ca\u0005=\u0000\u0000\u03ca\u00e0\u0001\u0000\u0000"+
"\u0000\u03cb\u03cc\u0005/\u0000\u0000\u03cc\u03cd\u0005=\u0000\u0000\u03cd"+
"\u00e2\u0001\u0000\u0000\u0000\u03ce\u03cf\u0005&\u0000\u0000\u03cf\u03d0"+
"\u0005=\u0000\u0000\u03d0\u00e4\u0001\u0000\u0000\u0000\u03d1\u03d2\u0005"+
"|\u0000\u0000\u03d2\u03d3\u0005=\u0000\u0000\u03d3\u00e6\u0001\u0000\u0000"+
"\u0000\u03d4\u03d5\u0005^\u0000\u0000\u03d5\u03d6\u0005=\u0000\u0000\u03d6"+
"\u00e8\u0001\u0000\u0000\u0000\u03d7\u03d8\u0005%\u0000\u0000\u03d8\u03d9"+
"\u0005=\u0000\u0000\u03d9\u00ea\u0001\u0000\u0000\u0000\u03da\u03db\u0005"+
"<\u0000\u0000\u03db\u03dc\u0005<\u0000\u0000\u03dc\u03dd\u0005=\u0000"+
"\u0000\u03dd\u00ec\u0001\u0000\u0000\u0000\u03de\u03df\u0005>\u0000\u0000"+
"\u03df\u03e0\u0005>\u0000\u0000\u03e0\u03e1\u0005=\u0000\u0000\u03e1\u00ee"+
"\u0001\u0000\u0000\u0000\u03e2\u03e3\u0005>\u0000\u0000\u03e3\u03e4\u0005"+
">\u0000\u0000\u03e4\u03e5\u0005>\u0000\u0000\u03e5\u03e6\u0005=\u0000"+
"\u0000\u03e6\u00f0\u0001\u0000\u0000\u0000\u03e7\u03e8\u0005-\u0000\u0000"+
"\u03e8\u03e9\u0005>\u0000\u0000\u03e9\u00f2\u0001\u0000\u0000\u0000\u03ea"+
"\u03eb\u0005:\u0000\u0000\u03eb\u03ec\u0005:\u0000\u0000\u03ec\u00f4\u0001"+
"\u0000\u0000\u0000\u03ed\u03ee\u0005@\u0000\u0000\u03ee\u00f6\u0001\u0000"+
"\u0000\u0000\u03ef\u03f0\u0005.\u0000\u0000\u03f0\u03f1\u0005.\u0000\u0000"+
"\u03f1\u03f2\u0005.\u0000\u0000\u03f2\u00f8\u0001\u0000\u0000\u0000\u03f3"+
"\u03f5\u0007\u0011\u0000\u0000\u03f4\u03f3\u0001\u0000\u0000\u0000\u03f5"+
"\u03f6\u0001\u0000\u0000\u0000\u03f6\u03f4\u0001\u0000\u0000\u0000\u03f6"+
"\u03f7\u0001\u0000\u0000\u0000\u03f7\u03f8\u0001\u0000\u0000\u0000\u03f8"+
"\u03f9\u0006|\u0000\u0000\u03f9\u00fa\u0001\u0000\u0000\u0000\u03fa\u03fb"+
"\u0005/\u0000\u0000\u03fb\u03fc\u0005*\u0000\u0000\u03fc\u0400\u0001\u0000"+
"\u0000\u0000\u03fd\u03ff\t\u0000\u0000\u0000\u03fe\u03fd\u0001\u0000\u0000"+
"\u0000\u03ff\u0402\u0001\u0000\u0000\u0000\u0400\u0401\u0001\u0000\u0000"+
"\u0000\u0400\u03fe\u0001\u0000\u0000\u0000\u0401\u0403\u0001\u0000\u0000"+
"\u0000\u0402\u0400\u0001\u0000\u0000\u0000\u0403\u0404\u0005*\u0000\u0000"+
"\u0404\u0405\u0005/\u0000\u0000\u0405\u0406\u0001\u0000\u0000\u0000\u0406"+
"\u0407\u0006}\u0000\u0000\u0407\u00fc\u0001\u0000\u0000\u0000\u0408\u0409"+
"\u0005/\u0000\u0000\u0409\u040a\u0005/\u0000\u0000\u040a\u040e\u0001\u0000"+
"\u0000\u0000\u040b\u040d\b\u0010\u0000\u0000\u040c\u040b\u0001\u0000\u0000"+
"\u0000\u040d\u0410\u0001\u0000\u0000\u0000\u040e\u040c\u0001\u0000\u0000"+
"\u0000\u040e\u040f\u0001\u0000\u0000\u0000\u040f\u0411\u0001\u0000\u0000"+
"\u0000\u0410\u040e\u0001\u0000\u0000\u0000\u0411\u0412\u0006~\u0000\u0000"+
"\u0412\u00fe\u0001\u0000\u0000\u0000\u0413\u0417\u0003\u010d\u0086\u0000"+
"\u0414\u0416\u0003\u010b\u0085\u0000\u0415\u0414\u0001\u0000\u0000\u0000"+
"\u0416\u0419\u0001\u0000\u0000\u0000\u0417\u0415\u0001\u0000\u0000\u0000"+
"\u0417\u0418\u0001\u0000\u0000\u0000\u0418\u0100\u0001\u0000\u0000\u0000"+
"\u0419\u0417\u0001\u0000\u0000\u0000\u041a\u041c\u0007\u0012\u0000\u0000"+
"\u041b\u041d\u0007\f\u0000\u0000\u041c\u041b\u0001\u0000\u0000\u0000\u041c"+
"\u041d\u0001\u0000\u0000\u0000\u041d\u041e\u0001\u0000\u0000\u0000\u041e"+
"\u041f\u0003\u0109\u0084\u0000\u041f\u0102\u0001\u0000\u0000\u0000\u0420"+
"\u0421\u0005\\\u0000\u0000\u0421\u0436\u0007\u0013\u0000\u0000\u0422\u0427"+
"\u0005\\\u0000\u0000\u0423\u0425\u0007\u0014\u0000\u0000\u0424\u0423\u0001"+
"\u0000\u0000\u0000\u0424\u0425\u0001\u0000\u0000\u0000\u0425\u0426\u0001"+
"\u0000\u0000\u0000\u0426\u0428\u0007\u0005\u0000\u0000\u0427\u0424\u0001"+
"\u0000\u0000\u0000\u0427\u0428\u0001\u0000\u0000\u0000\u0428\u0429\u0001"+
"\u0000\u0000\u0000\u0429\u0436\u0007\u0005\u0000\u0000\u042a\u042c\u0005"+
"\\\u0000\u0000\u042b\u042d\u0005u\u0000\u0000\u042c\u042b\u0001\u0000"+
"\u0000\u0000\u042d\u042e\u0001\u0000\u0000\u0000\u042e\u042c\u0001\u0000"+
"\u0000\u0000\u042e\u042f\u0001\u0000\u0000\u0000\u042f\u0430\u0001\u0000"+
"\u0000\u0000\u0430\u0431\u0003\u0107\u0083\u0000\u0431\u0432\u0003\u0107"+
"\u0083\u0000\u0432\u0433\u0003\u0107\u0083\u0000\u0433\u0434\u0003\u0107"+
"\u0083\u0000\u0434\u0436\u0001\u0000\u0000\u0000\u0435\u0420\u0001\u0000"+
"\u0000\u0000\u0435\u0422\u0001\u0000\u0000\u0000\u0435\u042a\u0001\u0000"+
"\u0000\u0000\u0436\u0104\u0001\u0000\u0000\u0000\u0437\u0440\u0003\u0107"+
"\u0083\u0000\u0438\u043b\u0003\u0107\u0083\u0000\u0439\u043b\u0005_\u0000"+
"\u0000\u043a\u0438\u0001\u0000\u0000\u0000\u043a\u0439\u0001\u0000\u0000"+
"\u0000\u043b\u043e\u0001\u0000\u0000\u0000\u043c\u043a\u0001\u0000\u0000"+
"\u0000\u043c\u043d\u0001\u0000\u0000\u0000\u043d\u043f\u0001\u0000\u0000"+
"\u0000\u043e\u043c\u0001\u0000\u0000\u0000\u043f\u0441\u0003\u0107\u0083"+
"\u0000\u0440\u043c\u0001\u0000\u0000\u0000\u0440\u0441\u0001\u0000\u0000"+
"\u0000\u0441\u0106\u0001\u0000\u0000\u0000\u0442\u0443\u0007\u0003\u0000"+
"\u0000\u0443\u0108\u0001\u0000\u0000\u0000\u0444\u044c\u0007\u0015\u0000"+
"\u0000\u0445\u0447\u0007\u0016\u0000\u0000\u0446\u0445\u0001\u0000\u0000"+
"\u0000\u0447\u044a\u0001\u0000\u0000\u0000\u0448\u0446\u0001\u0000\u0000"+
"\u0000\u0448\u0449\u0001\u0000\u0000\u0000\u0449\u044b\u0001\u0000\u0000"+
"\u0000\u044a\u0448\u0001\u0000\u0000\u0000\u044b\u044d\u0007\u0015\u0000"+
"\u0000\u044c\u0448\u0001\u0000\u0000\u0000\u044c\u044d\u0001\u0000\u0000"+
"\u0000\u044d\u010a\u0001\u0000\u0000\u0000\u044e\u0451\u0003\u010d\u0086"+
"\u0000\u044f\u0451\u0007\u0015\u0000\u0000\u0450\u044e\u0001\u0000\u0000"+
"\u0000\u0450\u044f\u0001\u0000\u0000\u0000\u0451\u010c\u0001\u0000\u0000"+
"\u0000\u0452\u0457\u0007\u0017\u0000\u0000\u0453\u0457\b\u0018\u0000\u0000"+
"\u0454\u0455\u0007\u0019\u0000\u0000\u0455\u0457\u0007\u001a\u0000\u0000"+
"\u0456\u0452\u0001\u0000\u0000\u0000\u0456\u0453\u0001\u0000\u0000\u0000"+
"\u0456\u0454\u0001\u0000\u0000\u0000\u0457\u010e\u0001\u0000\u0000\u0000"+
"3\u0000\u02d4\u02d9\u02dc\u02de\u02e1\u02e9\u02ed\u02f0\u02f6\u02fd\u0301"+
"\u0304\u030c\u0310\u0313\u0318\u031c\u031f\u0322\u0327\u032a\u032c\u0332"+
"\u0335\u0339\u033d\u0341\u034c\u0351\u0358\u035a\u0366\u036c\u036e\u03f6"+
"\u0400\u040e\u0417\u041c\u0424\u0427\u042e\u0435\u043a\u043c\u0440\u0448"+
"\u044c\u0450\u0456\u0001\u0000\u0001\u0000";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

View File

@ -1,242 +0,0 @@
ABSTRACT=1
ASSERT=2
BOOLEAN=3
BREAK=4
BYTE=5
CASE=6
CATCH=7
CHAR=8
CLASS=9
CONST=10
CONTINUE=11
DEFAULT=12
DO=13
DOUBLE=14
ELSE=15
ENUM=16
EXTENDS=17
FINAL=18
FINALLY=19
FLOAT=20
FOR=21
IF=22
GOTO=23
IMPLEMENTS=24
IMPORT=25
INSTANCEOF=26
INT=27
INTERFACE=28
LONG=29
NATIVE=30
NEW=31
PACKAGE=32
PRIVATE=33
PROTECTED=34
PUBLIC=35
RETURN=36
SHORT=37
STATIC=38
STRICTFP=39
SUPER=40
SWITCH=41
SYNCHRONIZED=42
THIS=43
THROW=44
THROWS=45
TRANSIENT=46
TRY=47
VOID=48
VOLATILE=49
WHILE=50
MODULE=51
OPEN=52
REQUIRES=53
EXPORTS=54
OPENS=55
TO=56
USES=57
PROVIDES=58
WITH=59
TRANSITIVE=60
VAR=61
YIELD=62
RECORD=63
SEALED=64
PERMITS=65
NON_SEALED=66
DECIMAL_LITERAL=67
HEX_LITERAL=68
OCT_LITERAL=69
BINARY_LITERAL=70
FLOAT_LITERAL=71
HEX_FLOAT_LITERAL=72
BOOL_LITERAL=73
CHAR_LITERAL=74
STRING_LITERAL=75
TEXT_BLOCK=76
NULL_LITERAL=77
LPAREN=78
RPAREN=79
LBRACE=80
RBRACE=81
LBRACK=82
RBRACK=83
SEMI=84
COMMA=85
DOT=86
ASSIGN=87
GT=88
LT=89
BANG=90
TILDE=91
QUESTION=92
COLON=93
EQUAL=94
LE=95
GE=96
NOTEQUAL=97
AND=98
OR=99
INC=100
DEC=101
ADD=102
SUB=103
MUL=104
DIV=105
BITAND=106
BITOR=107
CARET=108
MOD=109
ADD_ASSIGN=110
SUB_ASSIGN=111
MUL_ASSIGN=112
DIV_ASSIGN=113
AND_ASSIGN=114
OR_ASSIGN=115
XOR_ASSIGN=116
MOD_ASSIGN=117
LSHIFT_ASSIGN=118
RSHIFT_ASSIGN=119
URSHIFT_ASSIGN=120
ARROW=121
COLONCOLON=122
AT=123
ELLIPSIS=124
WS=125
COMMENT=126
LINE_COMMENT=127
IDENTIFIER=128
'abstract'=1
'assert'=2
'boolean'=3
'break'=4
'byte'=5
'case'=6
'catch'=7
'char'=8
'class'=9
'const'=10
'continue'=11
'default'=12
'do'=13
'double'=14
'else'=15
'enum'=16
'extends'=17
'final'=18
'finally'=19
'float'=20
'for'=21
'if'=22
'goto'=23
'implements'=24
'import'=25
'instanceof'=26
'int'=27
'interface'=28
'long'=29
'native'=30
'new'=31
'package'=32
'private'=33
'protected'=34
'public'=35
'return'=36
'short'=37
'static'=38
'strictfp'=39
'super'=40
'switch'=41
'synchronized'=42
'this'=43
'throw'=44
'throws'=45
'transient'=46
'try'=47
'void'=48
'volatile'=49
'while'=50
'module'=51
'open'=52
'requires'=53
'exports'=54
'opens'=55
'to'=56
'uses'=57
'provides'=58
'with'=59
'transitive'=60
'var'=61
'yield'=62
'record'=63
'sealed'=64
'permits'=65
'non-sealed'=66
'null'=77
'('=78
')'=79
'{'=80
'}'=81
'['=82
']'=83
';'=84
','=85
'.'=86
'='=87
'>'=88
'<'=89
'!'=90
'~'=91
'?'=92
':'=93
'=='=94
'<='=95
'>='=96
'!='=97
'&&'=98
'||'=99
'++'=100
'--'=101
'+'=102
'-'=103
'*'=104
'/'=105
'&'=106
'|'=107
'^'=108
'%'=109
'+='=110
'-='=111
'*='=112
'/='=113
'&='=114
'|='=115
'^='=116
'%='=117
'<<='=118
'>>='=119
'>>>='=120
'->'=121
'::'=122
'@'=123
'...'=124

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,242 +0,0 @@
ABSTRACT=1
ASSERT=2
BOOLEAN=3
BREAK=4
BYTE=5
CASE=6
CATCH=7
CHAR=8
CLASS=9
CONST=10
CONTINUE=11
DEFAULT=12
DO=13
DOUBLE=14
ELSE=15
ENUM=16
EXTENDS=17
FINAL=18
FINALLY=19
FLOAT=20
FOR=21
IF=22
GOTO=23
IMPLEMENTS=24
IMPORT=25
INSTANCEOF=26
INT=27
INTERFACE=28
LONG=29
NATIVE=30
NEW=31
PACKAGE=32
PRIVATE=33
PROTECTED=34
PUBLIC=35
RETURN=36
SHORT=37
STATIC=38
STRICTFP=39
SUPER=40
SWITCH=41
SYNCHRONIZED=42
THIS=43
THROW=44
THROWS=45
TRANSIENT=46
TRY=47
VOID=48
VOLATILE=49
WHILE=50
MODULE=51
OPEN=52
REQUIRES=53
EXPORTS=54
OPENS=55
TO=56
USES=57
PROVIDES=58
WITH=59
TRANSITIVE=60
VAR=61
YIELD=62
RECORD=63
SEALED=64
PERMITS=65
NON_SEALED=66
DECIMAL_LITERAL=67
HEX_LITERAL=68
OCT_LITERAL=69
BINARY_LITERAL=70
FLOAT_LITERAL=71
HEX_FLOAT_LITERAL=72
BOOL_LITERAL=73
CHAR_LITERAL=74
STRING_LITERAL=75
TEXT_BLOCK=76
NULL_LITERAL=77
LPAREN=78
RPAREN=79
LBRACE=80
RBRACE=81
LBRACK=82
RBRACK=83
SEMI=84
COMMA=85
DOT=86
ASSIGN=87
GT=88
LT=89
BANG=90
TILDE=91
QUESTION=92
COLON=93
EQUAL=94
LE=95
GE=96
NOTEQUAL=97
AND=98
OR=99
INC=100
DEC=101
ADD=102
SUB=103
MUL=104
DIV=105
BITAND=106
BITOR=107
CARET=108
MOD=109
ADD_ASSIGN=110
SUB_ASSIGN=111
MUL_ASSIGN=112
DIV_ASSIGN=113
AND_ASSIGN=114
OR_ASSIGN=115
XOR_ASSIGN=116
MOD_ASSIGN=117
LSHIFT_ASSIGN=118
RSHIFT_ASSIGN=119
URSHIFT_ASSIGN=120
ARROW=121
COLONCOLON=122
AT=123
ELLIPSIS=124
WS=125
COMMENT=126
LINE_COMMENT=127
IDENTIFIER=128
'abstract'=1
'assert'=2
'boolean'=3
'break'=4
'byte'=5
'case'=6
'catch'=7
'char'=8
'class'=9
'const'=10
'continue'=11
'default'=12
'do'=13
'double'=14
'else'=15
'enum'=16
'extends'=17
'final'=18
'finally'=19
'float'=20
'for'=21
'if'=22
'goto'=23
'implements'=24
'import'=25
'instanceof'=26
'int'=27
'interface'=28
'long'=29
'native'=30
'new'=31
'package'=32
'private'=33
'protected'=34
'public'=35
'return'=36
'short'=37
'static'=38
'strictfp'=39
'super'=40
'switch'=41
'synchronized'=42
'this'=43
'throw'=44
'throws'=45
'transient'=46
'try'=47
'void'=48
'volatile'=49
'while'=50
'module'=51
'open'=52
'requires'=53
'exports'=54
'opens'=55
'to'=56
'uses'=57
'provides'=58
'with'=59
'transitive'=60
'var'=61
'yield'=62
'record'=63
'sealed'=64
'permits'=65
'non-sealed'=66
'null'=77
'('=78
')'=79
'{'=80
'}'=81
'['=82
']'=83
';'=84
','=85
'.'=86
'='=87
'>'=88
'<'=89
'!'=90
'~'=91
'?'=92
':'=93
'=='=94
'<='=95
'>='=96
'!='=97
'&&'=98
'||'=99
'++'=100
'--'=101
'+'=102
'-'=103
'*'=104
'/'=105
'&'=106
'|'=107
'^'=108
'%'=109
'+='=110
'-='=111
'*='=112
'/='=113
'&='=114
'|='=115
'^='=116
'%='=117
'<<='=118
'>>='=119
'>>>='=120
'->'=121
'::'=122
'@'=123
'...'=124

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.13.2</version> <version>4.11</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 --> <!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
@ -26,7 +26,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.16.1</version> <version>2.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.github.classgraph</groupId> <groupId>io.github.classgraph</groupId>
@ -54,8 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<version>3.11.0</version> <version>3.11.0</version>
<configuration> <configuration>
<compilerArgs>--enable-preview</compilerArgs> <compilerArgs>--enable-preview</compilerArgs>
<source>22</source> <source>21</source>
<target>22</target> <target>21</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>

View File

@ -1,12 +1,9 @@
public class Box { public class Box<A> {
a; A a;
public Box() { } public Box() { }
public Box(a) { public Box(A a) {
//this.a = a; //this.a = a;
} }
set(x) {
a = x;
}
} }

View File

@ -1,15 +0,0 @@
import java.lang.Integer;
public class Assign {
public x = 10;
public y = this;
public call() {
return this;
}
public m() {
this.call().call().y.x = 20;
return x;
}
}

View File

@ -1 +0,0 @@
public record GenericRecord<T>(T a) {}

View File

@ -1,24 +0,0 @@
import java.lang.String;
import java.lang.Integer;
sealed interface List permits LinkedElem, Elem {}
public record LinkedElem<T>(T a,List l) implements List{}
public record Elem<T>(T c) implements List{}
public class GenericRecordSwitchCase {
public main(o) {
return switch(o) {
case LinkedElem(a, Elem(e)) -> a ;
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a;
};
}
}

View File

@ -1,20 +0,0 @@
import java.lang.Object;
import java.lang.Integer;
import java.lang.Float;
public record R(Object nested) {}
public class OverloadNestedPattern {
public Integer m(R(R(Integer a)), R(Integer b)) {
return 1;
}
public Integer m(R(R(Float a)), R(Float b)) {
return 2;
}
public Integer m(R(Integer a), R(Integer b)) {
return 3;
}
}

View File

@ -2,31 +2,15 @@ import java.lang.Integer;
import java.lang.Number; import java.lang.Number;
import java.lang.Float; import java.lang.Float;
public record Point(Number x, Number y) {} record Point(Number x, Number y) {}
public class OverloadPattern { public class OverloadPattern {
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) { public m(Point(Integer x, Integer y)) {
return 1; return x + y;
} }
public Number m(Point(Integer x, Integer y), Point(Integer a, Integer b)) { public m(Point(Float x, Float y)) {
return 2; return x * y;
}
public Number m(Point(Float x, Float y), Point(Integer a, Integer b)) {
return 3;
}
public Number m(Point(Float x, Float y), Point(Float a, Float b)) {
return 4;
}
public Number m(Point(Integer x, Integer y)) {
return 5;
}
public Number m(Point(Float x, Float y)) {
return 6;
} }
public m(Integer x) { public m(Integer x) {

View File

@ -1,21 +0,0 @@
import java.lang.Boolean;
sealed interface List<T> permits LinkedElem, Elem {}
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
public record Elem<T>(T a) implements List<T> {}
public class PatternMatchingHaskellStyle {
public append(LinkedElem(a, b), list2) {
return handleAppend(a, b, list2);
}
private handleAppend(a, Elem(e), list2) {
return new LinkedElem<>(a, new LinkedElem<>(e, list2));
}
private handleAppend(a, LinkedElem(e,r), list2) {
return new LinkedElem<>(a, append(new LinkedElem(e, r), list2));
}
}

View File

@ -1,26 +0,0 @@
import java.lang.Boolean;
import java.lang.Object;
sealed interface List<T> permits Cons, Empty {}
public record Cons<T>(T a, List<T> l) implements List<T> {}
public record Empty<T>() implements List<T> {}
public class PatternMatchingListAppend {
public append(Cons(a, b), list2) {
return new Cons<>(a, append(b, list2));
}
public append(Empty(), list2) {
return list2;
}
/*public append(a, list2) {
switch(a) {
case Cons(x, y) -> ...
case Empty() ->
}
}*/
}

View File

@ -1,17 +0,0 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.Number;
import java.lang.String;
public record R(Number n) {}
public class SwitchOverload {
public f(){}
public m(r) {
return switch(r) {
case R("test") -> f();
};
}
}

View File

@ -11,7 +11,7 @@ public class Switch {
case Rec(Integer a, Float b) -> a + 10; case Rec(Integer a, Float b) -> a + 10;
case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c; case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c;
case Integer i -> i; case Integer i -> i;
//default -> 0; default -> 0;
}; };
} }
} }

View File

@ -1,16 +0,0 @@
sealed interface List<T> permits LinkedElem, Elem {}
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
public record Elem<T>(T a) implements List<T> {}
public class SwitchAppend {
public append(l1, l2) {
return switch(l1) {
case LinkedElem(a, Elem(e)) -> new LinkedElem<>(a, new LinkedElem<>(e, l2));
case LinkedElem(a, r) -> new LinkedElem<>(a, append(r, l2));
//Alternativ:
//case LinkedElem(a, LinkedElem(e, r)) -> new LinkedElem<>(a, append(new LinkedElem(e, r), l2));
//default -> null;
};
}
}

View File

@ -1,22 +0,0 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
public class NumberOrText{}
public class Text extends NumberOrText{};
public class Number extends NumberOrText{};
public record Cons(Integer a, NumberOrText l){}
public class SwitchCaseHeritageDetection {
public main(o) {
return switch(o) {
case Cons(a, Text b) -> "Second Element is a Text";
case Cons(a, Number b) -> "Second Element is a Number";
default -> "None of the above cases";
};
}
}

View File

@ -1,17 +0,0 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
public record Rec(Object a, Object b) {}
public class SwitchInfered {
public main(o) {
return switch (o) {
case Rec(a, b) -> "asd";
default -> "cde";
};
}
}

View File

@ -1,14 +0,0 @@
import java.lang.Object;
import java.lang.Integer;
public record R(Integer i) {}
public class SwitchNestedValue {
public main(r) {
return switch(r) {
case R(10) -> 1;
case R(20) -> 2;
case R(i) -> 3;
};
}
}

View File

@ -1,21 +0,0 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.Number;
public record R(Number n) {}
public class SwitchOverload {
Number f(Double d) { return d * 2; }
Number f(Integer i) { return i * 5; }
public m(r, x) {
x = x + x;
return switch(r) {
case R(o) -> {
x = x + x;
yield f(o);
}
};
}
}

View File

@ -1,27 +0,0 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
sealed interface List permits LinkedElem, Elem {}
public record LinkedElem(Integer a,List l) implements List{} //Implementiert List und wird auch permittet
public record Elem(Integer c) implements List{} //Implementiert List, wird aber nicht permittet
public class SwitchCaseHeritageDetection {
public main(o) {
return switch(o) {
case LinkedElem(a, Elem(e)) -> a + e;
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a + e + f;
default -> 0;
};
}
}

View File

@ -654,17 +654,14 @@ primaryPattern
: typePattern #tPattern : typePattern #tPattern
| recordPattern #rPattern | recordPattern #rPattern
| '(' pattern ')' #enclosedPattern | '(' pattern ')' #enclosedPattern
| literal (',' literal)* #lPattern
; ;
recordPattern recordPattern
: typeType recordStructurePattern identifier? : typeType recordStructurePattern identifier?
//| recordStructurePattern identifier?
; ;
typePattern typePattern
: variableModifier* typeType identifier : variableModifier* typeType identifier
| variableModifier* identifier
; ;
recordStructurePattern recordStructurePattern
@ -720,10 +717,10 @@ switchLabeledRule
; ;
switchLabelCase switchLabelCase
: CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull : CASE expressionList (ARROW | COLON) #labeledRuleExprList
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
| CASE pattern (ARROW | COLON) #labeledRulePattern | CASE pattern (ARROW | COLON) #labeledRulePattern
| DEFAULT (ARROW | COLON) #labeledRuleDefault | DEFAULT (ARROW | COLON) #labeledRuleDefault
| CASE expressionList (ARROW | COLON) #labeledRuleExprList
; ;
// Java20 // Java20

View File

@ -13,7 +13,6 @@ import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
import de.dhbwstuttgart.target.tree.*; import de.dhbwstuttgart.target.tree.*;
import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import org.antlr.v4.codegen.Target;
import org.objectweb.asm.*; import org.objectweb.asm.*;
import java.lang.invoke.*; import java.lang.invoke.*;
@ -109,10 +108,6 @@ public class Codegen {
this.scope = this.scope.parent; this.scope = this.scope.parent;
} }
LocalVar createVariable(TargetType type) {
return createVariable("__var" + this.localCounter, type);
}
LocalVar createVariable(String name, TargetType type) { LocalVar createVariable(String name, TargetType type) {
var local = new LocalVar(localCounter, name, type); var local = new LocalVar(localCounter, name, type);
scope.add(local); scope.add(local);
@ -1299,7 +1294,8 @@ public class Codegen {
state.enterScope(); state.enterScope();
// This is the index to start the switch from // This is the index to start the switch from
mv.visitInsn(ICONST_0); mv.visitInsn(ICONST_0);
state.pushSwitch(); if (aSwitch.isExpression())
state.pushSwitch();
// To be able to skip ahead to the next case // To be able to skip ahead to the next case
var start = new Label(); var start = new Label();
@ -1343,7 +1339,11 @@ public class Codegen {
} }
} }
var defaultLabel = new Label(); var defaultLabel = end;
if (aSwitch.default_() != null) {
defaultLabel = new Label();
}
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
for (var i = 0; i < aSwitch.cases().size(); i++) { for (var i = 0; i < aSwitch.cases().size(); i++) {
@ -1378,18 +1378,11 @@ public class Codegen {
if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end); if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end);
} }
mv.visitLabel(defaultLabel);
if (aSwitch.default_() != null) { if (aSwitch.default_() != null) {
mv.visitLabel(defaultLabel);
generate(state, aSwitch.default_().body()); generate(state, aSwitch.default_().body());
if (aSwitch.default_().isSingleExpression() && aSwitch.isExpression()) if (aSwitch.default_().isSingleExpression() && aSwitch.isExpression())
yieldValue(state, aSwitch.default_().body().statements().get(0).type()); yieldValue(state, aSwitch.default_().body().statements().get(0).type());
} else {
// throw illegal argument exception on missing default case
mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
mv.visitInsn(DUP);
mv.visitLdcInsn("Unhandled case value");
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false);
mv.visitInsn(ATHROW);
} }
mv.visitLabel(end); mv.visitLabel(end);
@ -1397,10 +1390,8 @@ public class Codegen {
state.breakStack.pop(); state.breakStack.pop();
if (aSwitch.isExpression()) { if (aSwitch.isExpression()) {
if (aSwitch.type() != null) { mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
mv.visitVarInsn(ALOAD, state.switchResultValue.peek()); unboxPrimitive(state, aSwitch.type());
unboxPrimitive(state, aSwitch.type());
}
state.popSwitch(); state.popSwitch();
} }
@ -1411,50 +1402,30 @@ public class Codegen {
if (i >= clazz.getFieldDecl().size()) if (i >= clazz.getFieldDecl().size())
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'"); throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
var field = clazz.getFieldDecl().get(i); var field = clazz.getFieldDecl().get(i);
var fieldType = converter.convert(field.getType()); var fieldType = new TargetRefType(((RefType) field.getType()).getName().toString());
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false); state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
} }
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) { private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
if (pat.type() instanceof TargetPrimitiveType) if (pat.type() instanceof TargetPrimitiveType)
boxPrimitive(state, pat.type()); boxPrimitive(state, pat.type());
if (pat.type() instanceof TargetRefType) { state.mv.visitInsn(DUP);
state.mv.visitInsn(DUP); state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
var cont = new Label(); var cont = new Label();
state.mv.visitJumpInsn(IFNE, cont); state.mv.visitJumpInsn(IFNE, cont);
for (var i = 0; i < depth; i++) { for (var i = 0; i < depth; i++) {
state.mv.visitInsn(POP); state.mv.visitInsn(POP);
}
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
state.mv.visitLdcInsn(index + 1);
state.mv.visitJumpInsn(GOTO, start);
state.mv.visitLabel(cont);
state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
} }
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
state.mv.visitLdcInsn(index + 1);
state.mv.visitJumpInsn(GOTO, start);
state.mv.visitLabel(cont);
if (pat instanceof TargetExpressionPattern ep) { state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
var cur = state.createVariable(pat.type());
state.mv.visitVarInsn(ASTORE, cur.index);
var expr = new Equal(pat.type(), new TargetLocalVar(cur.type, cur.name), ep.expression()); if (pat instanceof TargetTypePattern sp) {
generate(state, expr);
var cont = new Label();
state.mv.visitJumpInsn(IFNE, cont);
for (var i = 0; i < depth - 1; i++) {
state.mv.visitInsn(POP);
}
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
state.mv.visitLdcInsn(index + 1);
state.mv.visitJumpInsn(GOTO, start);
state.mv.visitLabel(cont);
} else if (pat instanceof TargetTypePattern sp) {
var local = state.createVariable(sp.name(), sp.type()); var local = state.createVariable(sp.name(), sp.type());
state.mv.visitVarInsn(ASTORE, local.index); state.mv.visitVarInsn(ASTORE, local.index);
} else if (pat instanceof TargetComplexPattern cp) { } else if (pat instanceof TargetComplexPattern cp) {
@ -1545,26 +1516,29 @@ public class Codegen {
mv.visitEnd(); mv.visitEnd();
} }
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) { private int bindLocalVariables(State state, TargetPattern pattern, int offset, int field) {
state.mv.visitVarInsn(ALOAD, offset); if (pattern instanceof TargetComplexPattern cp) {
state.mv.visitVarInsn(ALOAD, offset);
var clazz = findClass(new JavaClassName(cp.type().name())); var clazz = findClass(new JavaClassName(cp.type().name()));
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found"); if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
for (var i = 0; i < cp.subPatterns().size(); i++) { for (var i = 0; i < cp.subPatterns().size(); i++) {
var subPattern = cp.subPatterns().get(i); var subPattern = cp.subPatterns().get(i);
if (i < cp.subPatterns().size() - 1) if (i < cp.subPatterns().size() - 1)
state.mv.visitInsn(DUP); state.mv.visitInsn(DUP);
extractField(state, cp.type(), i, clazz); extractField(state, cp.type(), i, clazz);
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName()); state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
offset = state.createVariable(subPattern.name(), subPattern.type()).index; state.mv.visitVarInsn(ASTORE, offset);
state.mv.visitVarInsn(ASTORE, offset); offset = bindLocalVariables(state, subPattern, offset, i);
if (subPattern instanceof TargetComplexPattern cp2) {
bindLocalVariables(state, cp2, offset);
} }
} } else if (pattern instanceof TargetTypePattern tp) {
offset++;
state.createVariable(tp.name(), tp.type());
} else throw new NotImplementedException();
return offset;
} }
private void generateMethod(TargetMethod method) { private void generateMethod(TargetMethod method) {
@ -1583,14 +1557,8 @@ public class Codegen {
if (method.block() != null) { if (method.block() != null) {
mv.visitCode(); mv.visitCode();
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1); var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
var offset = 1;
for (var param : method.signature().parameters()) { for (var param : method.signature().parameters()) {
state.createVariable(param.pattern().name(), param.pattern().type()); bindLocalVariables(state, param.pattern(), 1, 0);
}
for (var param : method.signature().parameters()) {
if (param.pattern() instanceof TargetComplexPattern cp)
bindLocalVariables(state, cp, offset);
offset++;
} }
generate(state, method.block()); generate(state, method.block());
if (method.signature().returnType() == null) if (method.signature().returnType() == null)
@ -1625,26 +1593,13 @@ public class Codegen {
if (!(clazz instanceof TargetInterface)) if (!(clazz instanceof TargetInterface))
access |= ACC_SUPER; access |= ACC_SUPER;
// Check sealed
for (var intf : clazz.implementingInterfaces()) {
var intfClass = compiler.getClass(new JavaClassName(intf.name()));
if (intfClass.isSealed()) {
if (intfClass.getPermittedSubtypes().stream().noneMatch(type -> type.getName().equals(new JavaClassName(className)))) {
throw new CodeGenException("Sealed interface " + intfClass.getClassName() + " doesn't permit class " + className);
}
}
}
var signature = generateSignature(clazz, clazz.generics()); var signature = generateSignature(clazz, clazz.generics());
var interfaces = clazz.implementingInterfaces().stream().map(TargetType::getInternalName).toArray(String[]::new); var interfaces = clazz.implementingInterfaces().stream().map(TargetType::getInternalName).toArray(String[]::new);
var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object"; var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object";
cw.visit(V1_8, access, clazz.qualifiedName().toString().replaceAll("\\.", "/"), signature, superType, interfaces); cw.visit(V1_8, access, clazz.qualifiedName().toString().replaceAll("\\.", "/"), signature, superType, interfaces);
if (clazz.txGenerics() != null && signature != null) { if (clazz.txGenerics() != null && signature != null)
var txSignature = generateSignature(clazz, clazz.txGenerics()); cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
if (txSignature != null)
cw.visitAttribute(new JavaTXSignatureAttribute(txSignature));
}
clazz.fields().forEach(this::generateField); clazz.fields().forEach(this::generateField);
clazz.constructors().forEach(this::generateConstructor); clazz.constructors().forEach(this::generateConstructor);
@ -1765,7 +1720,7 @@ public class Codegen {
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new)); bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
for (var i = 0; i < clazz.fields().size(); i++) { for (var i = 0; i < clazz.fields().size(); i++) {
var field = clazz.fields().get(i); var field = clazz.fields().get(i);
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toSignature(), false); var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
bootstrapArgs[i + 2] = fieldRef; bootstrapArgs[i + 2] = fieldRef;
} }

View File

@ -327,6 +327,74 @@ public class JavaTXCompiler {
logFile.write(ASTTypePrinter.print(f)); logFile.write(ASTTypePrinter.print(f));
} }
logFile.flush(); logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames);
unifyCons = unifyCons.map(x -> {
// Hier muss ueberlegt werden, ob
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
// PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
});
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons); varianceTPH = varianceInheritanceConstraintSet(unifyCons);
@ -393,6 +461,85 @@ public class JavaTXCompiler {
logFile.write(ASTTypePrinter.print(sf)); logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf)); System.out.println(ASTTypePrinter.print(sf));
logFile.flush(); logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames);
unifyCons = unifyCons.map(x -> {
// Hier muss ueberlegt werden, ob
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
// PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
});
// PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
// variance 1 gesetzt
// Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für
// Parameter die Typen der Argumente links stehen
// und die Typen der Rückgabewerte immer rechts stehen
/*
* unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> { if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) { ((PlaceholderType) x.getLhsType()).setVariance((byte)1); } else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) { ((PlaceholderType) x.getRhsType()).setVariance((byte)-1); } })));
*/
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString()); System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();

View File

@ -14,8 +14,6 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp;
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@ -103,6 +101,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.stringtemplate.v4.ST;
public class StatementGenerator { public class StatementGenerator {
@ -126,7 +125,7 @@ public class StatementGenerator {
this.superClass = superType; this.superClass = superType;
} }
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext, boolean methodparameters) { public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
List<Pattern> ret = new ArrayList<>(); List<Pattern> ret = new ArrayList<>();
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>(); List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
if (Objects.isNull(formalParameterListContext)) if (Objects.isNull(formalParameterListContext))
@ -148,12 +147,10 @@ public class StatementGenerator {
if (fp.typeType() != null) { if (fp.typeType() != null) {
type = TypeGenerator.convert(fp.typeType(), reg, generics); type = TypeGenerator.convert(fp.typeType(), reg, generics);
} else { } else {
type = methodparameters? type = TypePlaceholder.fresh(fp.getStart());
TypePlaceholder.fresh(fp.getStart(), 1, false)
: TypePlaceholder.fresh(fp.getStart());
} }
ret.add(new FormalParameter(paramName, type, fp.getStart())); ret.add(new FormalParameter(paramName, type, fp.getStart()));
localVars.put(paramName, type); localVars.put(paramName, type);
} }
} }
return new ParameterList(ret, ret.get(0).getOffset()); return new ParameterList(ret, ret.get(0).getOffset());
@ -442,7 +439,6 @@ public class StatementGenerator {
} }
private Pattern convert(PatternContext pattern) { private Pattern convert(PatternContext pattern) {
return switch (pattern) { return switch (pattern) {
case PPatternContext pPattern -> { case PPatternContext pPattern -> {
yield convert(pPattern.primaryPattern()); yield convert(pPattern.primaryPattern());
@ -457,36 +453,30 @@ public class StatementGenerator {
} }
private FormalParameter convert(PrimaryPatternContext pPattern) { private FormalParameter convert(PrimaryPatternContext pPattern) {
switch (pPattern) { switch (pPattern) {
case TPatternContext tPattern: case TPatternContext tPattern:
TypePatternContext typePattern = tPattern.typePattern(); TypePatternContext typePattern = tPattern.typePattern();
var text = typePattern.identifier().getText(); var text = typePattern.identifier().getText();
var type = typePattern.typeType() == null ? TypePlaceholder.fresh(pPattern.getStart()) : TypeGenerator.convert(typePattern.typeType(), reg, generics); var type = TypeGenerator.convert(typePattern.typeType(), reg, generics);
localVars.put(text, type); localVars.put(text, type);
return new FormalParameter(text, type, typePattern.getStart()); return new FormalParameter(text, type, typePattern.getStart());
case RPatternContext rPattern: case RPatternContext rPattern:
RecordPatternContext recordPattern = rPattern.recordPattern(); RecordPatternContext recordPattern = rPattern.recordPattern();
return convert(recordPattern); return convert(recordPattern);
case Java17Parser.LPatternContext patternContext: return new LiteralPattern(TypePlaceholder.fresh(patternContext.start), convert(patternContext.literal().get(0)), patternContext.start); default:
throw new NotImplementedException();
default:
throw new NotImplementedException();
} }
} }
private RecordPattern convert(RecordPatternContext recordPatternCtx) { private RecordPattern convert(RecordPatternContext recordPatternCtx) {
var cpl = recordPatternCtx.recordStructurePattern().recordComponentPatternList(); List<PatternContext> subPatternCtx = recordPatternCtx.recordStructurePattern().recordComponentPatternList().pattern();
List<PatternContext> subPatternCtx = cpl == null ? List.of() : cpl.pattern();
List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList()); List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList());
IdentifierContext identifierCtx = recordPatternCtx.identifier(); IdentifierContext identifierCtx = recordPatternCtx.identifier();
var text = (identifierCtx != null) ? identifierCtx.getText() : null; var text = (identifierCtx != null) ? identifierCtx.getText() : null;
//Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable var type = TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
var recordType = recordPatternCtx.typeType() == null ? TypePlaceholder.fresh(recordPatternCtx.getStart()) : TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics); if (text != null) localVars.put(text, type);
if (text != null) localVars.put(text, recordType); return new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
var ret = new RecordPattern(subPattern, text, recordType, TypePlaceholder.fresh(recordPatternCtx.getStart()), recordPatternCtx.getStart());
return ret;
} }
private Statement convert(Java17Parser.WhileloopContext stmt) { private Statement convert(Java17Parser.WhileloopContext stmt) {
@ -593,7 +583,7 @@ public class StatementGenerator {
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
var fieldEntry = fields.get(name.getText()); var fieldEntry = fields.get(name.getText());
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart())); return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
} }
private Statement convert(Java17Parser.BreakstmtContext stmt) { private Statement convert(Java17Parser.BreakstmtContext stmt) {
@ -707,7 +697,8 @@ public class StatementGenerator {
if (!Objects.isNull(expr.methodCall())) { if (!Objects.isNull(expr.methodCall())) {
return convert(expr.methodCall(), expr.expression(), offset); return convert(expr.methodCall(), expr.expression(), offset);
} else if (!Objects.isNull(expr.identifier())) { } else if (!Objects.isNull(expr.identifier())) {
return new FieldVar(convert(expr.expression()), expr.identifier().getText(), TypePlaceholder.fresh(expr.identifier().start), offset); // FIXME This is not the right way of handling any of this
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
} else { } else {
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite // Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
// generische Invokationen // generische Invokationen
@ -783,25 +774,64 @@ public class StatementGenerator {
/** /**
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden. * Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
* *
* @param expression * @param expression
* @param offset * @param offset
* @return * @return
*/ */
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) { private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
// Check for localVar: // FIXME Why does this take a String argument???
if (localVars.get(expression) != null) { String[] parts = expression.split("\\.");
return new LocalVar(expression, localVars.get(expression), offset); if (parts.length < 2) {
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die // Check for localVar:
// gleiche TPH bekommen if (localVars.get(expression) != null) {
return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset); return new LocalVar(expression, localVars.get(expression), offset);
} else if (reg.contains(expression)) { } else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
return generateStaticClassName(expression, offset); // gleiche TPH bekommen
} else { var field = fields.get(expression);
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
localVars.put(expression, TypePlaceholder.fresh(offset)); } else if (reg.contains(expression)) {
return new LocalVar(expression, localVars.get(expression), offset); return generateStaticClassName(expression, offset);
} else {
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
localVars.put(expression, TypePlaceholder.fresh(offset));
return new LocalVar(expression, localVars.get(expression), offset);
}
} }
return generateFieldVarOrClassname(expression, offset);
}
private Expression generateFieldVarOrClassname(String expression, Token offset) {
String[] parts = expression.split("\\.");
String whole = "";
Expression receiver = null;
for (String part : parts) {
whole += part;
// Check for Classname:
if (reg.contains(whole)) {
receiver = generateStaticClassName(whole, offset);
break;
}
whole += ".";
}
var fieldName = parts[parts.length - 1];
var isStatic = false;
if (parts.length < 2 || parts[0].contentEquals("this")) {
receiver = new This(offset);
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
} else if (parts[0].contentEquals("super")) {
receiver = new Super(TypePlaceholder.fresh(offset), offset);
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
receiver = generateLocalOrFieldVarOrClassName(part, offset);
} else {
StaticClassName cname = (StaticClassName) receiver;
var javaClassName = reg.getName(cname.getType().toString());
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier);
}
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
} }
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) { private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
@ -837,8 +867,10 @@ public class StatementGenerator {
private Statement convert(AssignexpressionContext expr) { private Statement convert(AssignexpressionContext expr) {
switch (expr.bop.getText()) { switch (expr.bop.getText()) {
case "=": case "=":
AssignLeftSide leftHandSide = convertAssignLHS(convert(expr.expression(0))); ExpressionContext leftside = expr.expression(0);
return new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart()); AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart());
Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
return ret;
case "+=": case "+=":
case "-=": case "-=":
case "*=": case "*=":
@ -855,8 +887,8 @@ public class StatementGenerator {
} }
} }
private AssignLeftSide convertAssignLHS(Expression expr) { private AssignLeftSide convert(String leftHandSide, Token start) {
Expression leftSide = expr; Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide, start);
if (leftSide instanceof FieldVar) if (leftSide instanceof FieldVar)
return new AssignToField((FieldVar) leftSide); return new AssignToField((FieldVar) leftSide);
else if (leftSide instanceof LocalVar) else if (leftSide instanceof LocalVar)
@ -1069,7 +1101,7 @@ public class StatementGenerator {
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else if (lambdaParams.formalParameterList() != null) { } else if (lambdaParams.formalParameterList() != null) {
params = convert(lambdaParams.formalParameterList(), false); params = convert(lambdaParams.formalParameterList());
// }else if( lambdaParams.inferredFormalParameterList != null){ // }else if( lambdaParams.inferredFormalParameterList != null){
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) { } else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
List<Pattern> parameterList = new ArrayList<>(); List<Pattern> parameterList = new ArrayList<>();

View File

@ -269,7 +269,7 @@ public class SyntaxTreeGenerator {
} }
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset)); fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset)); constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset); FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset)); constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
Statement returnStatement = new Return(fieldvar, offset); Statement returnStatement = new Return(fieldvar, offset);
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset)); methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
@ -393,12 +393,12 @@ public class SyntaxTreeGenerator {
if (!Objects.isNull(ctx.EXTENDS())) { if (!Objects.isNull(ctx.EXTENDS())) {
extendedInterfaces.addAll(convert(ctx.typeList(0), generics)); extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
} }
List<RefType> permittedSubtypes = null; List<RefType> permittedSubtypes = new ArrayList<>();
// Ist Bit für 'sealed'-Modifier gesetzt // Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) { if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) { if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration') // permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics)); permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else { } else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt // falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration"); throw new NotImplementedException("Invalid sealed class declaration");
@ -435,7 +435,7 @@ public class SyntaxTreeGenerator {
} }
} }
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList(), true); ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
MethodBodyContext body = bodydeclaration.methodBody(); MethodBodyContext body = bodydeclaration.methodBody();
Block block = null; Block block = null;
if (!(body instanceof EmptymethodContext)) { if (!(body instanceof EmptymethodContext)) {
@ -532,7 +532,7 @@ public class SyntaxTreeGenerator {
RefTypeOrTPHOrWildcardOrGeneric retType; RefTypeOrTPHOrWildcardOrGeneric retType;
if (Objects.isNull(header.refType())) { if (Objects.isNull(header.refType())) {
retType = TypePlaceholder.fresh(header.getStart(), -1, false); retType = TypePlaceholder.fresh(header.getStart());
} else { } else {
if (header.refType() instanceof RefType2Context reftype) { if (header.refType() instanceof RefType2Context reftype) {
retType = TypeGenerator.convert(reftype.typeType(), reg, generics); retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
@ -541,7 +541,7 @@ public class SyntaxTreeGenerator {
} }
} }
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList(), true); ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
MethodBodyContext body = methoddeclaration.methodBody(); MethodBodyContext body = methoddeclaration.methodBody();
Block block = null; Block block = null;
if (body instanceof EmptymethodContext emptymethod) { if (body instanceof EmptymethodContext emptymethod) {
@ -581,7 +581,7 @@ public class SyntaxTreeGenerator {
} }
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics); RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList(), true); ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass); Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart()); return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
} }
@ -594,7 +594,7 @@ public class SyntaxTreeGenerator {
} else { } else {
// PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die // PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
// Modifier zu bekommen // Modifier zu bekommen
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart(), -1, false); fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart());
} }
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) { for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
String fieldName = varDecl.variableDeclaratorId().getText(); String fieldName = varDecl.variableDeclaratorId().getText();

View File

@ -10,8 +10,6 @@ public interface ASTVisitor extends StatementVisitor{
void visit(FormalParameter formalParameter); void visit(FormalParameter formalParameter);
void visit(LiteralPattern literalPattern);
void visit(GenericDeclarationList genericTypeVars); void visit(GenericDeclarationList genericTypeVars);
void visit(Field field); void visit(Field field);

View File

@ -37,11 +37,6 @@ public abstract class AbstractASTWalker implements ASTVisitor {
formalParameter.getType().accept((ASTVisitor) this); formalParameter.getType().accept((ASTVisitor) this);
} }
@Override
public void visit(LiteralPattern literalPattern) {
}
@Override @Override
public void visit(GenericDeclarationList genericTypeVars) { public void visit(GenericDeclarationList genericTypeVars) {
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator(); Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();

View File

@ -86,9 +86,6 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
return staticInitializer; return staticInitializer;
} }
public boolean isSealed() { return permittedSubtypes != null; }
public List<RefType> getPermittedSubtypes() { return permittedSubtypes != null ? permittedSubtypes : List.of(); }
public boolean isInterface() { public boolean isInterface() {
return (Modifier.INTERFACE & this.getModifiers()) != 0; return (Modifier.INTERFACE & this.getModifiers()) != 0;
} }

View File

@ -1,29 +0,0 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.Pattern;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import org.antlr.v4.runtime.Token;
public class LiteralPattern extends FormalParameter
{
public final Expression value;
public LiteralPattern(RefTypeOrTPHOrWildcardOrGeneric type, Expression value, Token offset) {
super(null, type, offset);
this.value = value;
}
@Override
public FormalParameter withType(RefTypeOrTPHOrWildcardOrGeneric type) {
return new LiteralPattern(type, value, getOffset());
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -3,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
@ -11,12 +10,15 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class RecordPattern extends FormalParameter { public class RecordPattern extends FormalParameter {
private final List<Pattern> subPattern; private final List<Pattern> subPattern;
public final RefTypeOrTPHOrWildcardOrGeneric recordType;
public RecordPattern(List<Pattern> subPattern, String name, RefTypeOrTPHOrWildcardOrGeneric recordType, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) { public RecordPattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset);
subPattern = new ArrayList<>();
}
public RecordPattern(List<Pattern> subPattern, String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset); super(name, type, offset);
this.subPattern = subPattern; this.subPattern = subPattern;
this.recordType = recordType;
} }
public List<Pattern> getSubPattern() { public List<Pattern> getSubPattern() {

View File

@ -3,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
public interface StatementVisitor { public interface StatementVisitor {
void visit(ArgumentList argumentList); void visit(ArgumentList argumentList);

View File

@ -34,6 +34,7 @@ public class ASTFactory {
private static final HashMap<java.lang.Class, ClassOrInterface> cache = new HashMap<>(); private static final HashMap<java.lang.Class, ClassOrInterface> cache = new HashMap<>();
public static ClassOrInterface createClass(java.lang.Class jreClass) { public static ClassOrInterface createClass(java.lang.Class jreClass) {
System.out.println(jreClass);
if (cache.containsKey(jreClass)) if (cache.containsKey(jreClass))
return cache.get(jreClass); return cache.get(jreClass);
@ -173,6 +174,7 @@ public class ASTFactory {
superClass = (RefType) createType(java.lang.Object.class); superClass = (RefType) createType(java.lang.Object.class);
} }
List<RefType> implementedInterfaces = new ArrayList<>(); List<RefType> implementedInterfaces = new ArrayList<>();
System.out.println(jreClass);
for (Type jreInterface : jreClass.getGenericInterfaces()) { for (Type jreInterface : jreClass.getGenericInterfaces()) {
implementedInterfaces.add((RefType) createType(jreInterface)); implementedInterfaces.add((RefType) createType(jreInterface));
} }

View File

@ -129,10 +129,9 @@ public class UnifyTypeFactory {
if (tph.getName().equals("AFR")) { if (tph.getName().equals("AFR")) {
System.out.println("XXX"+innerType); System.out.println("XXX"+innerType);
} }
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance()); PlaceholderType ntph = new PlaceholderType(tph.getName());
ntph.setVariance(tph.getVariance()); ntph.setVariance(tph.getVariance());
ntph.setOrCons(tph.getOrCons()); ntph.setOrCons(tph.getOrCons());
ntph.setWildcardtable(tph.getWildcardtable());
int in = PLACEHOLDERS.indexOf(ntph); int in = PLACEHOLDERS.indexOf(ntph);
if (in == -1) { if (in == -1) {
PLACEHOLDERS.add(ntph); PLACEHOLDERS.add(ntph);

View File

@ -17,11 +17,13 @@ public class FieldVar extends Expression {
public final String fieldVarName; public final String fieldVarName;
public final Expression receiver; public final Expression receiver;
public final boolean isStatic;
public FieldVar(Expression receiver, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) { public FieldVar(Expression receiver, boolean isStatic, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset); super(type, offset);
this.fieldVarName = fieldVarName; this.fieldVarName = fieldVarName;
this.receiver = receiver; this.receiver = receiver;
this.isStatic = isStatic;
} }
@Override @Override

View File

@ -8,7 +8,6 @@ import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects;
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
@ -50,7 +49,10 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
@Override @Override
public int hashCode() { public int hashCode() {
return this.name.hashCode();//Nur den Name hashen. Sorgt ¼r langsame, aber funktionierende HashMaps int hash = 0;
hash += super.hashCode();
hash += this.name.hashCode();//Nur den Name hashen. Sorgt ¼r langsame, aber funktionierende HashMaps
return hash;
} }
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) { public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
@ -81,7 +83,6 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
if(obj instanceof RefType){ if(obj instanceof RefType){
if (!Objects.equals(this.name, ((RefType) obj).name)) return false;
boolean ret = true; boolean ret = true;
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden //if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden

View File

@ -21,17 +21,9 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
private final String name; private final String name;
/** /**
* variance shows the variance of the pair * wird im Generate Generics Teil nach der Rueckumwandlung nach dem Unify genutzt
* 1: contravariant
* -1 covariant
* 0 invariant
*/
private int variance = 0;
/**
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf
*/ */
private boolean wildcardable = true; private int variance = 0;
/* /*
* Fuer Oder-Constraints: * Fuer Oder-Constraints:
@ -47,12 +39,10 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
* Factory-Methode <code>fresh()</code> erzeugt. * Factory-Methode <code>fresh()</code> erzeugt.
* <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle * <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
*/ */
private TypePlaceholder(String name, Token offset, int variance, boolean wildcardable) private TypePlaceholder(String name, Token offset)
{ {
super(offset); super(offset);
this.name = name; this.name = name;
this.variance = variance;
this.wildcardable = wildcardable;
} }
@ -63,15 +53,11 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
* @return * @return
*/ */
public static TypePlaceholder fresh(Token position){ public static TypePlaceholder fresh(Token position){
return new TypePlaceholder(NameGenerator.makeNewName(), position, 0, true); return new TypePlaceholder(NameGenerator.makeNewName(), position);
}
public static TypePlaceholder fresh(Token position, int variance, boolean wildcardable){
return new TypePlaceholder(NameGenerator.makeNewName(), position, variance, wildcardable);
} }
public static RefTypeOrTPHOrWildcardOrGeneric of(String name) { public static RefTypeOrTPHOrWildcardOrGeneric of(String name) {
return new TypePlaceholder(name, new NullToken(),0, true); return new TypePlaceholder(name, new NullToken());
} }
@ -134,9 +120,4 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
public byte getOrCons() { public byte getOrCons() {
return orCons; return orCons;
} }
public Boolean getWildcardtable() {
return wildcardable;
}
} }

View File

@ -57,11 +57,6 @@ public class OutputGenerator implements ASTVisitor {
out.append(formalParameter.getName()); out.append(formalParameter.getName());
} }
@Override
public void visit(LiteralPattern literalPattern) {
literalPattern.value.accept(this);
}
@Override @Override
public void visit(GenericDeclarationList genericTypeVars) { public void visit(GenericDeclarationList genericTypeVars) {
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator(); Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
@ -513,11 +508,12 @@ public class OutputGenerator implements ASTVisitor {
aRecordPattern.getType().accept(this); aRecordPattern.getType().accept(this);
out.append("("); out.append("(");
List<Pattern> subPatterns = aRecordPattern.getSubPattern(); List<Pattern> subPatterns = aRecordPattern.getSubPattern();
for (var i = 0; i < subPatterns.size(); i++) { int i;
for (i = 0; i < subPatterns.size() - 1; i++) {
subPatterns.get(i).accept(this); subPatterns.get(i).accept(this);
if (i < subPatterns.size() - 1) out.append(", ");
out.append(", ");
} }
subPatterns.get(i).accept(this);
String name; String name;
if ((name = aRecordPattern.getName()) != null) if ((name = aRecordPattern.getName()) != null)
out.append(name); out.append(name);

View File

@ -1,10 +1,10 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.bytecode.CodeGenException;
import de.dhbwstuttgart.bytecode.FunNGenerator; import de.dhbwstuttgart.bytecode.FunNGenerator;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.ByteArrayClassLoader; import de.dhbwstuttgart.environment.ByteArrayClassLoader;
import de.dhbwstuttgart.environment.IByteArrayClassLoader; import de.dhbwstuttgart.environment.IByteArrayClassLoader;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
@ -17,7 +17,6 @@ import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import de.dhbwstuttgart.typeinference.result.*; import de.dhbwstuttgart.typeinference.result.*;
import java.lang.annotation.Target;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -34,18 +33,12 @@ public class ASTToTargetAST {
protected List<Generics> all; protected List<Generics> all;
public Generics generics; public Generics generics;
public List<Generics> currentMethodOverloads;
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>(); final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>(); final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
private Method currentMethod; private Method currentMethod;
public final JavaTXCompiler compiler; public final JavaTXCompiler compiler;
public List<RefTypeOrTPHOrWildcardOrGeneric> findAllVariants(RefTypeOrTPHOrWildcardOrGeneric type) {
return javaGenerics().stream().map(generics -> generics.resolve(type)).distinct().toList();
}
public List<GenericsResult> txGenerics() { public List<GenericsResult> txGenerics() {
return all.stream().map(generics -> new GenericsResult(generics.txGenerics)).toList(); return all.stream().map(generics -> new GenericsResult(generics.txGenerics)).toList();
} }
@ -145,112 +138,38 @@ public class ASTToTargetAST {
return ret; return ret;
} }
// This is used to serve as a custom equality to signature that performs a weak check without going into record patterns.
// The two signatures are considered equal if all the argument types match.
// This also turns equal if both types implement a sealed super interface
class PatternSignature {
final TargetMethod.Signature signature;
final String name;
PatternSignature(String name, TargetMethod.Signature signature) {
this.signature = signature;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof PatternSignature other)) return false;
if (!this.name.equals(other.name)) return false;
if (other.signature.parameters().size() != signature.parameters().size()) return false;
for (var i = 0; i < signature.parameters().size(); i++) {
var p1 = signature.parameters().get(i).pattern().type();
var p2 = other.signature.parameters().get(i).pattern().type();
if (p1 instanceof TargetGenericType && p2 instanceof TargetGenericType) continue;
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1, p2).isEmpty()) return false;
}
return true;
}
@Override
public int hashCode() {
return signature.parameters().size();
}
}
// This finds a common sealed interface type to group together methods that use different records
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createClass(Object.class));
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
var res = new HashSet<ClassOrInterface>();
var cla = compiler.getClass(new JavaClassName(ta.name()));
var clb = compiler.getClass(new JavaClassName(tb.name()));
if (cla.equals(clb) && cla.isInterface() && cla.isSealed()) {
res.add(cla);
}
while (!cla.equals(ASTFactory.createClass(Object.class))) {
var clb2 = clb;
while (!clb2.equals(ASTFactory.createClass(Object.class))) {
for (var intfa : cla.getSuperInterfaces()) {
for (var intfb : clb.getSuperInterfaces()) {
if (intfa.equals(intfb)) {
var clintf = compiler.getClass(intfa.getName());
if (clintf.isSealed()) {
res.add(clintf);
}
}
}
}
clb2 = compiler.getClass(clb2.getSuperClass().getName());
}
cla = compiler.getClass(cla.getSuperClass().getName());
}
return res.stream().toList();
}
return List.of();
}
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) { public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
var mapOfSignatures = new HashMap<PatternSignature, List<TargetMethod>>(); var res = new ArrayList<List<TargetMethod>>();
for (var method : methods) { for (var method : methods) {
// Convert all methods // Convert all methods
var methodsWithTphs = convert(input, method); var methodsWithTphs = convert(input, method);
// Then check for methods with the same signature // Then check for methods with the same signature
var resMethods = new HashSet<MethodWithTphs>(); var mapOfSignatures = new HashMap<TargetMethod.Signature, List<MethodWithTphs>>();
for (var m : methodsWithTphs) {
var methodsWithSameSignature = mapOfSignatures.getOrDefault(m.method.signature(), new ArrayList<>());
methodsWithSameSignature.add(m);
mapOfSignatures.put(m.method.signature(), methodsWithSameSignature);
}
outer: var resMethods = new HashSet<TargetMethod>();
for (var m1 : methodsWithTphs) { for (var methodsWithSignature : mapOfSignatures.values()) {
for (var m2 : methodsWithTphs) { outer: for (var m1 : methodsWithSignature) {
for (var i = 0; i < m1.args.size(); i++) { for (var m2 : methodsWithSignature) {
var arg1 = m1.args.get(i); for (var i = 0; i < m1.args.size(); i++) {
var arg2 = m2.args.get(i); var arg1 = m1.args.get(i);
if (arg1.parameter.equals(arg2.parameter)) { var arg2 = m2.args.get(i);
if (isSupertype(arg1.signature, arg2.signature) && if (arg1.parameter.equals(arg2.parameter)) {
if (isSupertype(arg1.signature, arg2.signature) &&
!arg1.signature.equals(arg2.signature)) continue outer; !arg1.signature.equals(arg2.signature)) continue outer;
}
} }
} }
resMethods.add(m1.method);
} }
resMethods.add(m1);
}
for (var m : resMethods) {
var signature = new PatternSignature(m.method.name(), m.method.signature());
var methodsWithSameSignature = mapOfSignatures.getOrDefault(signature, new ArrayList<>());
methodsWithSameSignature.add(m.method);
mapOfSignatures.put(signature, methodsWithSameSignature);
} }
res.add(resMethods.stream().toList());
} }
return res;
mapOfSignatures.values().forEach(e -> {
e.forEach(e2 -> {
System.out.println(e2.name() + " -> " + e2.signature().parameters().stream().map(m -> m.pattern().type()).toList());
});
System.out.println();
});
return mapOfSignatures.values().stream().toList();
} }
public TargetStructure convert(ClassOrInterface input) { public TargetStructure convert(ClassOrInterface input) {
@ -283,7 +202,7 @@ public class ASTToTargetAST {
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList(); var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList(); var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
var fields = input.getFieldDecl().stream().map(this::convert).toList(); var fields = input.getFieldDecl().stream().map(this::convert).toList();
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream).toList(); var methods = groupOverloads(input, input.getMethods()).stream().flatMap(List::stream).toList();
TargetMethod staticConstructor = null; TargetMethod staticConstructor = null;
if (input.getStaticInitializer().isPresent()) if (input.getStaticInitializer().isPresent())
@ -297,14 +216,9 @@ public class ASTToTargetAST {
} }
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) { public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
var res = new ArrayList<MethodParameter>(); return input.getFormalparalist().stream().map(param ->
for (var i = 0; i < input.getFormalparalist().size(); i++) { new MethodParameter((TargetPattern) convert(param))
var param = input.getFormalparalist().get(i); ).toList();
var pattern = (TargetPattern) convert(param);
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
res.add(new MethodParameter(pattern));
}
return res;
} }
private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) { private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
@ -353,155 +267,69 @@ public class ASTToTargetAST {
return result; return result;
} }
private String encodeName(String name, TargetMethod.Signature params) { private String encodeName(String name, ParameterList params) {
var res = new StringBuilder(); var res = new StringBuilder();
res.append(name); res.append(name);
res.append('$'); res.append('$');
for (var param : params.parameters()) { for (var param : params.getFormalparalist()) {
encodeName(param.pattern(), res); if (param instanceof RecordPattern rp) {
res.append(FunNGenerator.encodeType(convert(param.getType())));
for (var pattern : rp.getSubPattern()) {
res.append(FunNGenerator.encodeType(convert(pattern.getType())));
}
}
} }
return res.toString(); return res.toString();
} }
private void encodeName(TargetPattern pattern, StringBuilder res) { private List<TargetMethod> convert(ClassOrInterface clazz, List<Method> overloadedMethods) {
if (pattern instanceof TargetComplexPattern cp) { if (overloadedMethods.size() == 1) {
res.append(FunNGenerator.encodeType(cp.type())); return convert(clazz, overloadedMethods.getFirst()).stream().map(m -> m.method()).toList();
for (var pat : cp.subPatterns()) {
encodeName(pat, res);
}
} else {
res.append(FunNGenerator.encodeType(pattern.type()));
} }
} var methods = new ArrayList<Method>();
private TargetType unwrap(TargetType type) {
if (type instanceof TargetRefType ref) {
if (!ref.params().isEmpty()) return new TargetRefType(ref.name());
}
return type;
}
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
if (methods.size() == 1) {
var method = methods.getFirst();
var mParams = new ArrayList<TargetExpression>();
for (var i = 0; i < params.size(); i++) {
var tpe = method.signature().parameters().get(i).pattern().type();
mParams.add(new TargetLocalVar(tpe, params.get(i).name()));
}
TargetExpression caseBody = new TargetMethodCall(
method.signature().returnType(),
new TargetThis(classType),
mParams,
classType,
method.name(),
false, false, method.isPrivate()
);
if (method.signature().returnType() != null) {
caseBody = new TargetReturn(caseBody);
}
return caseBody;
}
var cases = new ArrayList<TargetSwitch.Case>();
var usedPatterns = new HashSet<TargetType>();
for (var method : methods) {
var patternsRec = new ArrayList<>(patterns);
TargetExpression expr = null;
var i = 0;
for (var param : method.signature().parameters()) {
if (i == offset) {
patternsRec.add(param.pattern());
}
if (i > offset) {
// Find next pattern
expr = params.get(i);
break;
}
i++;
}
var lastPattern = patternsRec.getLast();
var type = unwrap(lastPattern.type());
if (usedPatterns.contains(type)) continue;
usedPatterns.add(type);
var candidates = methods.stream().filter(m -> {
var j = 0;
for (var param : m.signature().parameters()) {
if (j >= patternsRec.size()) return true;
if (!patternsRec.get(j).type().equals(param.pattern().type())) return false;
j++;
}
return true;
}).toList();
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
var body = new TargetBlock(List.of(caseBody));
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
cases.add(case_);
}
return new TargetSwitch(switchExpr, cases, null, true);
}
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
if (true) return overloadedMethods;
if (overloadedMethods.size() <= 1) return overloadedMethods;
// Check if we have a pattern as a parameter
var firstMethod = overloadedMethods.getFirst();
var secondMethod = overloadedMethods.get(1);
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) return overloadedMethods;
// Rename existing methods
var res = new ArrayList<TargetMethod>();
for (var method : overloadedMethods) { for (var method : overloadedMethods) {
var name = encodeName(method.name(), method.signature()); var newMethod = new Method(
res.add(new TargetMethod(method.access(), name, method.block(), method.signature(), method.txSignature())); method.modifier,
method.name,
//encodeName(method.name, method.getParameterList()),
method.getReturnType(),
method.getParameterList(),
method.block,
method.getGenerics(),
method.getOffset()
);
methods.add(newMethod);
} }
var signatureParams = new ArrayList<MethodParameter>(); // TODO Record overloading
for (var i = 0; i < firstMethod.signature().parameters().size(); i++) { /*var template = overloadedMethods.get(0);
var p1 = firstMethod.signature().parameters().get(i).pattern();
var t1 = p1.type(); var pParams = new ArrayList<Pattern>();
var t2 = secondMethod.signature().parameters().get(i).pattern().type(); var i = 0;
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2)); for (var par : template.getParameterList()) {
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) { pParams.add(switch (par) {
var t3 = m.signature().parameters().get(i).pattern().type(); case RecordPattern rp -> new RecordPattern(rp.getSubPattern(), "par" + i, rp.getType(), new NullToken());
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3)); default -> par;
});
i++;
}
var params = new ParameterList(pParams, new NullToken());
var statements = new ArrayList<Statement>();
statements.add(new Return(makeRecordSwitch(template.getReturnType(), params, res), new NullToken()));
var block = new Block(statements, new NullToken());
var entryPoint = new Method(template.modifier, template.name, template.getReturnType(), params, block, template.getGenerics(), new NullToken());
res.add(entryPoint); // TODO*/
var res = new ArrayList<TargetMethod>();
for (var method : methods) {
var overloads = convert(clazz, method);
for (var m : overloads) {
var overload = m.method;
if (res.contains(overload)) throw new CodeGenException("Duplicate method found: " + overload.name() + " with signature " + overload.signature().getSignature());
res.add(overload);
} }
if (commonSubTypes.size() != 1) throw new DebugException("Invalid overload");
// TODO accept multiple types
var superType = commonSubTypes.iterator().next();
String name;
if (p1 instanceof TargetComplexPattern) name = "__var" + i;
else name = p1.name();
signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name));
} }
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(firstMethod.signature().returnType(), secondMethod.signature().returnType()));
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
commonSubTypes.retainAll(commonSuperInterfaceTypes(firstMethod.signature().returnType(), m.signature().returnType()));
}
var returnType = commonSubTypes.isEmpty() ? TargetType.Object : new TargetRefType(commonSubTypes.iterator().next().getClassName().toString());
var parameters = signatureParams.stream().map( p -> new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
//var patterns = List.of((TargetComplexPattern) firstMethod.signature().parameters().stream()
// .filter(p -> p.pattern() instanceof TargetComplexPattern).findFirst().orElseThrow().pattern());
// Generate dispatch method
var classType = new TargetRefType(clazz.getClassName().getClassName());
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(signatureParams.getFirst().pattern().type(), signatureParams.getFirst().pattern().name()), parameters, List.of(), res, classType);
var block = new TargetBlock(List.of(stmt));
var signature = new TargetMethod.Signature(Set.of(), signatureParams, returnType);
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, signature, firstMethod.txSignature());
res.add(bridgeMethod);
return res; return res;
} }
@ -548,16 +376,11 @@ public class ASTToTargetAST {
record MethodWithTphs(TargetMethod method, List<SignaturePairTarget> args) {} record MethodWithTphs(TargetMethod method, List<SignaturePairTarget> args) {}
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) { private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
generics = all.getFirst(); generics = all.getFirst();
List<MethodWithTphs> result = new ArrayList<>(); List<MethodWithTphs> result = new ArrayList<>();
this.currentMethod = method; this.currentMethod = method;
List<Signature> signatures = new ArrayList<>();
HashMap<TargetMethod.Signature, List<Generics>> collectedGenerics = new HashMap<>();
for (var s : all) { for (var s : all) {
generics = s; generics = s;
var javaGenerics = this.generics.javaGenerics.generics(currentClass, method); var javaGenerics = this.generics.javaGenerics.generics(currentClass, method);
@ -581,18 +404,8 @@ public class ASTToTargetAST {
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType); var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics)); var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), javaSignature, txSignature);
signatures.add(new Signature(javaSignature, txSignature, generics));
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
listOfGenerics.add(generics);
collectedGenerics.put(javaSignature, listOfGenerics);
}
for (var signature : signatures) {
generics = signature.generics;
currentMethodOverloads = collectedGenerics.get(signature.java);
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList(); var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
result.add(new MethodWithTphs(newMethod, concreteParams)); result.add(new MethodWithTphs(newMethod, concreteParams));
@ -605,9 +418,7 @@ public class ASTToTargetAST {
var list = new ArrayList<MethodParameter>(); var list = new ArrayList<MethodParameter>();
for (var i = 0; i < paraList.getFormalparalist().size(); i++) { for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
var param = paraList.getParameterAt(i); var param = paraList.getParameterAt(i);
var pattern = (TargetPattern) convert(param); list.add(new MethodParameter((TargetPattern) convert(param)).withType(convert(superList.getParameterAt(i).getType(), generics)));
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics)));
} }
return list; return list;
} }

View File

@ -1,7 +1,10 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
@ -131,8 +134,8 @@ public abstract class GenerateGenerics {
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>(); final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
final Set<PairLT> simplifiedConstraints = new HashSet<>(); final Set<PairLT> simplifiedConstraints = new HashSet<>();
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>(); final Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>(); final Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) { GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
this.astToTargetAST = astToTargetAST; this.astToTargetAST = astToTargetAST;
@ -151,41 +154,6 @@ public abstract class GenerateGenerics {
System.out.println("Simplified constraints: " + simplifiedConstraints); System.out.println("Simplified constraints: " + simplifiedConstraints);
} }
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
public GenericsState store() {
return new GenericsState(new HashMap<>(concreteTypes), new HashMap<>(equality));
}
public void restore(GenericsState state) {
this.concreteTypes = state.concreteTypes;
this.equality = state.equality;
}
public void addOverlay(TypePlaceholder from, RefTypeOrTPHOrWildcardOrGeneric to) {
if (to instanceof TypePlaceholder t) equality.put(from, t);
else if (to instanceof RefType t) concreteTypes.put(new TPH(from), t);
}*/
Set<TPH> findTypeVariables(ParameterList params) {
var res = new HashSet<TPH>();
for (var param : params.getFormalparalist()) {
res.addAll(findTypeVariables(param));
}
return res;
}
Set<TPH> findTypeVariables(Pattern pattern) {
var res = new HashSet<TPH>();
if (pattern instanceof RecordPattern rp) {
for (var subPattern : rp.getSubPattern()) {
res.addAll(findTypeVariables(subPattern));
}
}
res.addAll(findTypeVariables(pattern.getType()));
return res;
}
Set<TPH> findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) { Set<TPH> findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) {
var result = new HashSet<TPH>(); var result = new HashSet<TPH>();
if (type instanceof TypePlaceholder tph) { if (type instanceof TypePlaceholder tph) {
@ -522,7 +490,9 @@ public abstract class GenerateGenerics {
if (!(method instanceof Constructor)) if (!(method instanceof Constructor))
typeVariables.addAll(findTypeVariables(method.getReturnType())); typeVariables.addAll(findTypeVariables(method.getReturnType()));
typeVariables.addAll(findTypeVariables(method.getParameterList())); for (var arg : method.getParameterList().getFormalparalist()) {
typeVariables.addAll(findTypeVariables(arg.getType()));
}
if (method.block != null) if (method.block != null)
method.block.accept(new TracingStatementVisitor() { method.block.accept(new TracingStatementVisitor() {
@ -586,7 +556,9 @@ public abstract class GenerateGenerics {
var usedTphs = new HashSet<TPH>(); var usedTphs = new HashSet<TPH>();
// For eliminating inner type variables we need to figure out which ones are actually used // For eliminating inner type variables we need to figure out which ones are actually used
usedTphs.addAll(findTypeVariables(method.getParameterList())); for (var param : method.getParameterList().getFormalparalist()) {
usedTphs.addAll(findTypeVariables(param.getType()));
}
usedTphs.addAll(findTypeVariables(method.getReturnType())); usedTphs.addAll(findTypeVariables(method.getReturnType()));
referenced.addAll(usedTphs); referenced.addAll(usedTphs);
referenced.addAll(typeVariablesOfClass); referenced.addAll(typeVariablesOfClass);
@ -684,21 +656,11 @@ public abstract class GenerateGenerics {
if (p1 instanceof PairLT ptph && ptph.left.resolve().equals(ptph.right.resolve())) if (p1 instanceof PairLT ptph && ptph.left.resolve().equals(ptph.right.resolve()))
result.remove(p1); // TODO This is a bit strange result.remove(p1); // TODO This is a bit strange
} }
for (var tph : usedTphs) { for (var tph : usedTphs) {
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph))) if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
addToPairs(result, new PairEQ(tph, ASTToTargetAST.OBJECT)); addToPairs(result, new PairEQ(tph, ASTToTargetAST.OBJECT));
} }
var all = new HashSet<>(result);
for (var p : all) {
if (p instanceof PairEQ peq && peq.right.equals(ASTToTargetAST.OBJECT)) {
for (var p2 : all) {
if (p2 instanceof PairLT && p2.left.equals(p.left)) {
result.remove(p);
break;
}
}
}
}
} }
private record ToAdd(TypePlaceholder left, TypePlaceholder right) {} private record ToAdd(TypePlaceholder left, TypePlaceholder right) {}

View File

@ -1,21 +1,24 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.PrimitiveMethodsGenerator;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.target.tree.MethodParameter; import de.dhbwstuttgart.target.tree.MethodParameter;
import de.dhbwstuttgart.target.tree.TargetGeneric;
import de.dhbwstuttgart.target.tree.TargetMethod; import de.dhbwstuttgart.target.tree.TargetMethod;
import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.expression.*;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import javax.swing.text.html.Option;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
public class StatementToTargetExpression implements ASTVisitor { public class StatementToTargetExpression implements ASTVisitor {
@ -140,11 +143,7 @@ public class StatementToTargetExpression implements ASTVisitor {
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
var isStatic = false; result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), fieldVar.isStatic, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
var type = converter.convert(fieldVar.receiver.getType());
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
result = new TargetFieldVar(converter.convert(fieldVar.getType()), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
} }
@Override @Override
@ -387,94 +386,9 @@ public class StatementToTargetExpression implements ASTVisitor {
result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse)); result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse));
} }
record TypeVariants(RefTypeOrTPHOrWildcardOrGeneric in, List<RefTypeOrTPHOrWildcardOrGeneric> types) {}
private List<TypeVariants> extractAllPatterns(Pattern pattern) {
return switch (pattern) {
case GuardedPattern guarded -> extractAllPatterns(guarded.getNestedPattern());
case RecordPattern recordPattern -> recordPattern.getSubPattern().stream()
.map(this::extractAllPatterns)
.flatMap(List::stream).toList();
case FormalParameter param -> List.of(new TypeVariants(param.getType(), converter.findAllVariants(param.getType())));
default -> List.of();
};
}
record TypePair(RefTypeOrTPHOrWildcardOrGeneric in, RefTypeOrTPHOrWildcardOrGeneric out) {}
private void cartesianProduct(
List<TypeVariants> variants, int index,
List<RefTypeOrTPHOrWildcardOrGeneric> current,
List<List<RefTypeOrTPHOrWildcardOrGeneric>> result) {
if (index == variants.size()) {
result.add(new ArrayList<>(current));
return;
}
var currentSet = variants.get(index).types;
for (var element: currentSet) {
current.add(element);
cartesianProduct(variants, index + 1, current, result);
current.removeLast();
}
}
private List<List<TypePair>> cartesianProduct(List<TypeVariants> variants) {
var prod = new ArrayList<List<RefTypeOrTPHOrWildcardOrGeneric>>();
cartesianProduct(variants, 0, new ArrayList<>(), prod);
var res = new ArrayList<List<TypePair>>();
for (var list : prod) {
var l = new ArrayList<TypePair>();
for (var i = 0; i < list.size(); i++) {
l.add(new TypePair(variants.get(i).in, list.get(i)));
}
res.add(l);
}
return res;
}
@Override @Override
public void visit(Switch switchStmt) { public void visit(Switch switchStmt) {
var variants = converter.findAllVariants(switchStmt.getSwitch().getType()); var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList();
var returns = converter.findAllVariants(switchStmt.getType());
var canBeOverloaded = variants.size() == 1 && returns.size() == 1;
var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(case_ -> {
var overloads = new ArrayList<TargetSwitch.Case>();
if (canBeOverloaded) {
for (var label: case_.getLabels()) {
var product = cartesianProduct(extractAllPatterns(label.getPattern()));
for (var l : product) {
var oldGenerics = converter.generics;
// Set the generics to matching result set
for (var generics : converter.currentMethodOverloads) {
var java = generics.javaGenerics();
var equals = true;
for (var pair : l) {
if (!java.getType(pair.in).equals(pair.out)) {
equals = false; break;
}
}
if (equals) {
converter.generics = generics;
break;
}
}
overloads.add(converter.convert(case_));
converter.generics = oldGenerics;
}
}
} else {
overloads.add(converter.convert(case_));
}
return overloads;
}).flatMap(List::stream).toList();
TargetSwitch.Case default_ = null; TargetSwitch.Case default_ = null;
for (var block : switchStmt.getBlocks()) { for (var block : switchStmt.getBlocks()) {
@ -568,11 +482,6 @@ public class StatementToTargetExpression implements ASTVisitor {
result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName()); result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName());
} }
@Override
public void visit(LiteralPattern literalPattern) {
result = new TargetExpressionPattern(converter.convert(literalPattern.value));
}
@Override @Override
public void visit(ExpressionPattern aPattern) { public void visit(ExpressionPattern aPattern) {
result = converter.convert(aPattern.getExpression()); result = converter.convert(aPattern.getExpression());

View File

@ -11,8 +11,4 @@ public record MethodParameter(TargetPattern pattern) {
public MethodParameter withType(TargetType type) { public MethodParameter withType(TargetType type) {
return new MethodParameter(pattern.withType(type)); return new MethodParameter(pattern.withType(type));
} }
public MethodParameter withName(String name) {
return new MethodParameter(pattern.withName(name));
}
} }

View File

@ -18,19 +18,6 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
public String getDescriptor() { public String getDescriptor() {
return TargetMethod.getDescriptor(returnType, parameters.stream().map(MethodParameter::pattern).map(TargetPattern::type).toArray(TargetType[]::new)); return TargetMethod.getDescriptor(returnType, parameters.stream().map(MethodParameter::pattern).map(TargetPattern::type).toArray(TargetType[]::new));
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Signature signature = (Signature) o;
return Objects.equals(parameters, signature.parameters);
}
@Override
public int hashCode() {
return Objects.hash(parameters);
}
} }
public static String getDescriptor(TargetType returnType, TargetType... parameters) { public static String getDescriptor(TargetType returnType, TargetType... parameters) {
@ -79,10 +66,6 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
return (access & Opcodes.ACC_STATIC) != 0; return (access & Opcodes.ACC_STATIC) != 0;
} }
public boolean isPrivate() {
return (access & Opcodes.ACC_PRIVATE) != 0;
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof TargetMethod otherMethod)) return false; if (!(other instanceof TargetMethod otherMethod)) return false;

View File

@ -9,9 +9,4 @@ public record TargetComplexPattern(TargetType type, String name, List<TargetPatt
public TargetComplexPattern withType(TargetType type) { public TargetComplexPattern withType(TargetType type) {
return new TargetComplexPattern(type, name, subPatterns); return new TargetComplexPattern(type, name, subPatterns);
} }
@Override
public TargetComplexPattern withName(String name) {
return new TargetComplexPattern(type, name, subPatterns);
}
} }

View File

@ -1,20 +0,0 @@
package de.dhbwstuttgart.target.tree.expression;
import de.dhbwstuttgart.target.tree.type.TargetType;
public record TargetExpressionPattern(TargetExpression expression) implements TargetPattern {
@Override
public TargetPattern withType(TargetType type) {
return this;
}
@Override
public TargetType type() {
return expression.type();
}
@Override
public TargetPattern withName(String name) {
return this;
}
}

View File

@ -12,9 +12,4 @@ public record TargetGuard(TargetPattern inner, TargetExpression expression) impl
public TargetType type() { public TargetType type() {
return inner.type(); return inner.type();
} }
@Override
public TargetGuard withName(String name) {
return new TargetGuard(inner.withName(name), expression);
}
} }

View File

@ -2,7 +2,7 @@ package de.dhbwstuttgart.target.tree.expression;
import de.dhbwstuttgart.target.tree.type.TargetType; import de.dhbwstuttgart.target.tree.type.TargetType;
public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetExpressionPattern, TargetGuard, TargetTypePattern { public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetGuard, TargetTypePattern {
default String name() { default String name() {
return null; return null;
} }
@ -10,6 +10,4 @@ public sealed interface TargetPattern extends TargetExpression permits TargetCom
TargetPattern withType(TargetType type); TargetPattern withType(TargetType type);
TargetType type(); TargetType type();
TargetPattern withName(String name);
} }

View File

@ -7,9 +7,4 @@ public record TargetTypePattern(TargetType type, String name) implements TargetP
public TargetTypePattern withType(TargetType type) { public TargetTypePattern withType(TargetType type) {
return new TargetTypePattern(type, name); return new TargetTypePattern(type, name);
} }
@Override
public TargetTypePattern withName(String name) {
return new TargetTypePattern(type, name);
}
} }

View File

@ -13,7 +13,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
public class TypeInsertPlacer extends AbstractASTWalker { public class TypeInsertPlacer extends AbstractASTWalker{
Set<TypeInsert> inserts = new HashSet<>(); Set<TypeInsert> inserts = new HashSet<>();
private ResultSet withResults; private ResultSet withResults;
String pkgName; String pkgName;

View File

@ -1,22 +1,15 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.SourceLoc;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.Statement; import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.util.BiRelation; import de.dhbwstuttgart.util.BiRelation;
import org.antlr.v4.runtime.Token;
import java.util.*; import java.util.*;
@ -86,60 +79,8 @@ public class TYPE {
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m); TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo); TYPEStmt methodScope = new TYPEStmt(blockInfo);
ConstraintSet constraintSet = new ConstraintSet();
m.getParameterList().getFormalparalist().forEach(el -> {
if(el instanceof RecordPattern){
constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInfo));
}
});
m.block.accept(methodScope); m.block.accept(methodScope);
constraintSet.addAll(methodScope.getConstraints()); return methodScope.getConstraints();
return constraintSet;
}
public ConstraintSet addRecursiveParameterConstraints(RecordPattern recordPattern, TypeInferenceBlockInformation blockInformation){
ConstraintSet constraintSet = new ConstraintSet();
var subPatternList = recordPattern.getSubPattern();
var resolver = new GenericsResolverSameName();
var refType = (RefType) resolver.visit((RefType) recordPattern.recordType);
var allClasses = blockInformation.getAvailableClasses();
var typename = refType.getName().getClassName();
ClassOrInterface allClass = allClasses.stream().filter(c -> c.getClassName().getClassName().equals(typename)).findFirst().orElseThrow();
// Constraints on the type of the pattern itself
constraintSet.addUndConstraint(new Pair(refType, recordPattern.getType(), PairOperator.SMALLERDOT));
for (var superInterface : allClass.getSuperInterfaces()) {
constraintSet.addUndConstraint(new Pair(recordPattern.getType(), resolver.visit(superInterface), PairOperator.SMALLERDOT));
}
int counter = 0;
for (Pattern el : subPatternList){
if (el instanceof RecordPattern){
constraintSet.addAll(addRecursiveParameterConstraints((RecordPattern) el, blockInformation));
} else {
FormalParameter param = (FormalParameter) allClass.getConstructors().getFirst().getParameterList().getParameterAt(counter);
FieldAssumption assumption = new FieldAssumption(param.getName(), allClass, param.getType(), blockInformation.getCurrentTypeScope());
var fieldCons = new Pair(el.getType(), assumption.getType(resolver), PairOperator.EQUALSDOT);
var recvCons = new Pair(refType, assumption.getReceiverType(resolver), PairOperator.EQUALSDOT);
constraintSet.addUndConstraint(fieldCons);
constraintSet.addUndConstraint(recvCons);
for (var i = 0; i < refType.getParaList().size(); i++) {
constraintSet.addUndConstraint(new Pair(refType.getParaList().get(i),
((RefType)assumption.getReceiverType(resolver)).getParaList().get(i),
PairOperator.EQUALSDOT));
}
}
counter++;
}
return constraintSet;
} }
private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) { private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {

View File

@ -1,6 +1,7 @@
//PL 2018-12-19: Merge chekcen //PL 2018-12-19: Merge chekcen
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
import java.sql.Ref;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -47,13 +48,11 @@ public class TYPEStmt implements StatementVisitor {
private SourceLoc loc(Token token) { private SourceLoc loc(Token token) {
return new SourceLoc(info.getCurrentClass().getFileName(), token.getLine()); return new SourceLoc(info.getCurrentClass().getFileName(), token.getLine());
} };
;
/** /**
* Erstellt einen neuen GenericResolver Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird. * Erstellt einen neuen GenericResolver Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
* *
* @return * @return
*/ */
private static GenericsResolver getResolverInstance() { private static GenericsResolver getResolverInstance() {
@ -117,8 +116,6 @@ public class TYPEStmt implements StatementVisitor {
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this); fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>(); Set<Constraint> oderConstraints = new HashSet<>();
for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) { for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
@ -130,6 +127,7 @@ public class TYPEStmt implements StatementVisitor {
throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
} }
@Override @Override
public void visit(ForStmt forStmt) { public void visit(ForStmt forStmt) {
forStmt.initializer.forEach(s -> s.accept(this)); forStmt.initializer.forEach(s -> s.accept(this));
@ -237,7 +235,7 @@ public class TYPEStmt implements StatementVisitor {
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken()); private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken()); private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken()); private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
private final RefType charr = new RefType(ASTFactory.createClass(Character.class).getClassName(), new NullToken()); private final RefType charr = new RefType(ASTFactory.createClass(Character.class).getClassName(), new NullToken());
@Override @Override
@ -263,13 +261,13 @@ public class TYPEStmt implements StatementVisitor {
binary.lexpr.accept(this); binary.lexpr.accept(this);
binary.rexpr.accept(this); binary.rexpr.accept(this);
if (binary.operation.equals(BinaryExpr.Operator.DIV) if (binary.operation.equals(BinaryExpr.Operator.DIV)
|| binary.operation.equals(BinaryExpr.Operator.MUL) || binary.operation.equals(BinaryExpr.Operator.MUL)
|| binary.operation.equals(BinaryExpr.Operator.MOD) || binary.operation.equals(BinaryExpr.Operator.MOD)
|| binary.operation.equals(BinaryExpr.Operator.ADD) || binary.operation.equals(BinaryExpr.Operator.ADD)
|| binary.operation.equals(BinaryExpr.Operator.SUB) || binary.operation.equals(BinaryExpr.Operator.SUB)
|| binary.operation.equals(BinaryExpr.Operator.OR) || binary.operation.equals(BinaryExpr.Operator.OR)
|| binary.operation.equals(BinaryExpr.Operator.AND) || binary.operation.equals(BinaryExpr.Operator.AND)
|| binary.operation.equals(BinaryExpr.Operator.XOR)) { || binary.operation.equals(BinaryExpr.Operator.XOR)) {
Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>(); Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
@ -332,7 +330,7 @@ public class TYPEStmt implements StatementVisitor {
} }
/* /*
* PL auskommentiert Anfang 2018-07-17 /* In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben * PL auskommentiert Anfang 2018-07-17 /* In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben
* *
* numeric = new Constraint<>(); numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); PL auskommentiert Ende 2018-07-17 * numeric = new Constraint<>(); numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); PL auskommentiert Ende 2018-07-17
*/ */
@ -356,7 +354,7 @@ public class TYPEStmt implements StatementVisitor {
* shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); * shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
* numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new * numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new
* Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); * Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric);
* *
* //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch constraintsSet.addOderConstraint(numericRelationConcatenation); //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch * //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch constraintsSet.addOderConstraint(numericRelationConcatenation); //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
*/ */
// Testeise eingefuegt PL 2018-05-24 // Testeise eingefuegt PL 2018-05-24
@ -630,14 +628,14 @@ public class TYPEStmt implements StatementVisitor {
public static RefTypeOrTPHOrWildcardOrGeneric getReceiverType(ClassOrInterface receiver, GenericsResolver resolver) { public static RefTypeOrTPHOrWildcardOrGeneric getReceiverType(ClassOrInterface receiver, GenericsResolver resolver) {
if (receiver == null) return null; if (receiver == null) return null;
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar gtv : receiver.getGenerics()) { for(GenericTypeVar gtv : receiver.getGenerics()){
//Die Generics werden alle zu TPHs umgewandelt. //Die Generics werden alle zu TPHs umgewandelt.
params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken()))); params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
} }
RefTypeOrTPHOrWildcardOrGeneric receiverType; RefTypeOrTPHOrWildcardOrGeneric receiverType;
if (receiver instanceof FunNClass) { if(receiver instanceof FunNClass){
receiverType = new RefType(new JavaClassName(receiver.getClassName().toString() + "$$"), params, new NullToken()); // new FunN(params); receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params);
} else { }else{
receiverType = new RefType(receiver.getClassName(), params, new NullToken()); receiverType = new RefType(receiver.getClassName(), params, new NullToken());
} }
@ -656,7 +654,7 @@ public class TYPEStmt implements StatementVisitor {
ClassOrInterface receiverCl = assumption.getReceiver(); ClassOrInterface receiverCl = assumption.getReceiver();
/* /*
* List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); for(GenericTypeVar gtv : receiverCl.getGenerics()){ //Die Generics werden alle zu TPHs umgewandelt. params.add(resolver.resolve(gtv.getName())); } * List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); for(GenericTypeVar gtv : receiverCl.getGenerics()){ //Die Generics werden alle zu TPHs umgewandelt. params.add(resolver.resolve(gtv.getName())); }
* *
* RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset()); * RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
*/ */
@ -778,7 +776,7 @@ public class TYPEStmt implements StatementVisitor {
// TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden // TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/* /*
* BEispiel: auto test = new List<String>(); test.add("hallo"); * BEispiel: auto test = new List<String>(); test.add("hallo");
* *
* Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A> Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String * Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A> Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/ */
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -823,10 +821,6 @@ public class TYPEStmt implements StatementVisitor {
public void visit(Switch switchStmt) { public void visit(Switch switchStmt) {
switchStack.push(switchStmt); switchStack.push(switchStmt);
if(switchStmt.getSwitch().getType() instanceof TypePlaceholder){
((TypePlaceholder) switchStmt.getSwitch().getType()).setVariance(-1);
}
RefTypeOrTPHOrWildcardOrGeneric caseExpressionType = null; RefTypeOrTPHOrWildcardOrGeneric caseExpressionType = null;
for (var child : switchStmt.getBlocks()) { for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) { for (var label : child.getLabels()) {
@ -840,34 +834,7 @@ public class TYPEStmt implements StatementVisitor {
if (caseExpressionType == null) { if (caseExpressionType == null) {
for (var child : switchStmt.getBlocks()) { for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) { for (var label : child.getLabels()) {
if (label.getPattern() == null) { if (label.getPattern() instanceof FormalParameter) {
//System.out.println("DefaultCase");
} else {
constraintsSet.addUndConstraint(
new Pair(
label.getPattern().getType(),
switchStmt.getSwitch().getType(),
PairOperator.SMALLERDOT,
loc(label.getOffset())
)
);
}
}
}
} else {
constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(switchStmt.getSwitch().getOffset())));
}
if (caseExpressionType == null) {
for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) {
if (label.getPattern() == null) {
constraintsSet.addUndConstraint(new Pair(new RefType(new JavaClassName("java.lang.Object"), new NullToken()), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
}
if (label.getPattern() instanceof RecordPattern) {
RecordPattern recordPattern = (RecordPattern) label.getPattern();
//constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
} else if (label.getPattern() instanceof FormalParameter) {
constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset()))); constraintsSet.addUndConstraint(new Pair(label.getPattern().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT, loc(label.getOffset())));
} }
} }
@ -876,50 +843,14 @@ public class TYPEStmt implements StatementVisitor {
constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(switchStmt.getSwitch().getOffset()))); constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT, loc(switchStmt.getSwitch().getOffset())));
} }
for (var child : switchStmt.getBlocks()) { for (var child : switchStmt.getBlocks()) {
child.getLabels().forEach(el -> {
if (el.getType() instanceof RefType) {
var recType = el;
if (el.getPattern() instanceof RecordPattern) {
var pattern = (RecordPattern) recType.getPattern();
recursivelyAddRecordConstraints(pattern);
}
}
});
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT, loc(switchStmt.getOffset())));
child.accept(this); child.accept(this);
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT, loc(switchStmt.getOffset())));
} }
switchStack.pop(); switchStack.pop();
} }
public void recursivelyAddRecordConstraints(RecordPattern pattern) {
var allClasses = info.getAvailableClasses();
var interestingClasses = allClasses.stream().filter(as -> as.getClassName().equals(((RefType) pattern.getType()).getName())).toList();
var constructors = interestingClasses.get(0).getConstructors();
int counter = 0;
for (var subPattern : pattern.getSubPattern()) {
for (Constructor con : constructors) {
//System.out.println("----------------------\n" + subPattern.getType() + " | " + con.getParameterList().getParameterAt(counter).getType() + "\n----------------------\n");
constraintsSet.addUndConstraint(new Pair(subPattern.getType(), con.getParameterList().getParameterAt(counter).getType(), PairOperator.SMALLERDOT, loc(con.getParameterList().getParameterAt(counter).getOffset())));
}
if (subPattern instanceof RecordPattern) recursivelyAddRecordConstraints((RecordPattern) subPattern);
else if (subPattern instanceof LiteralPattern lp) lp.value.accept(this);
counter++;
}
}
@Override @Override
public void visit(SwitchBlock switchBlock) { public void visit(SwitchBlock switchBlock) {
for (var stmt : switchBlock.statements) { for (var stmt : switchBlock.statements) {
@ -929,6 +860,7 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(SwitchLabel switchLabel) { public void visit(SwitchLabel switchLabel) {
// TODO Auto-generated method stub
} }
@Override @Override

View File

@ -53,8 +53,8 @@ public final class PlaceholderType extends UnifyType{
/** /**
* variance shows the variance of the pair * variance shows the variance of the pair
* 1: contravariant * -1: contravariant
* -1 covariant * 1 covariant
* 0 invariant * 0 invariant
* PL 2018-03-21 * PL 2018-03-21
*/ */
@ -77,14 +77,6 @@ public final class PlaceholderType extends UnifyType{
IsGenerated = false; // This type is user generated IsGenerated = false; // This type is user generated
} }
public PlaceholderType(String name, int variance) {
super(name, new TypeParams());
EXISTING_PLACEHOLDERS.add(name); // Add to list of existing placeholder names
IsGenerated = false; // This type is user generated
this.variance = variance;
}
/** /**
* Creates a new placeholdertype * Creates a new placeholdertype
* @param isGenerated true if this placeholder is auto-generated, false if it is user-generated. * @param isGenerated true if this placeholder is auto-generated, false if it is user-generated.

View File

@ -64,11 +64,11 @@ public class AllgemeinTest {
//String className = "Cycle"; //String className = "Cycle";
//String className = "TripleTest"; //String className = "TripleTest";
//String className = "WildcardList"; //String className = "WildcardList";
String className = "List"; //String className = "List";
//String className = "Box"; //String className = "Box";
//String className = "GenBox"; //String className = "GenBox";
//String className = "InnerInf"; //String className = "InnerInf";
//String className = "Foo"; String className = "Foo";
//PL 2019-10-24: genutzt fuer unterschiedliche Tests //PL 2019-10-24: genutzt fuer unterschiedliche Tests
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav"; path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav"; //path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";

View File

@ -4,6 +4,7 @@ import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.AbstractList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
@ -11,7 +12,7 @@ import java.util.Vector;
import targetast.TestCodegen; import targetast.TestCodegen;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static targetast.TestCodegen.generateClassFiles; import static targetast.TestCodegen.generateClassFiles;
public class TestComplete { public class TestComplete {
@Test @Test
@ -656,13 +657,6 @@ public class TestComplete {
System.out.println(clazz.getDeclaredMethod("toString").invoke(instance)); System.out.println(clazz.getDeclaredMethod("toString").invoke(instance));
} }
@Test
public void genericRecordTest() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "GenericRecord.jav");
var clazz = classFiles.get("GenericRecord");
var instance = clazz.getDeclaredConstructor(Object.class).newInstance((Object) null);
}
@Test @Test
public void testSwitch() throws Exception { public void testSwitch() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Switch.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Switch.jav");
@ -680,153 +674,9 @@ public class TestComplete {
assertEquals(swtch.invoke(instance, r2), 20); assertEquals(swtch.invoke(instance, r2), 20);
assertEquals(swtch.invoke(instance, r3), 40); assertEquals(swtch.invoke(instance, r3), 40);
assertEquals(swtch.invoke(instance, 50), 50); assertEquals(swtch.invoke(instance, 50), 50);
try { assertEquals(swtch.invoke(instance, "Some string"), 0);
assertEquals(swtch.invoke(instance, "Some string"), 0);
fail("No assertion thrown!");
} catch (InvocationTargetException exception) {
assertTrue(exception.getCause() instanceof IllegalArgumentException);
assertEquals(exception.getCause().getMessage(), "Unhandled case value");
}
} }
@Test
public void testSwitchInfered() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchInfered.jav");
var clazz = classFiles.get("SwitchInfered");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var record = classFiles.get("Rec");
var ctor = record.getDeclaredConstructor(Object.class, Object.class);
var r1 = ctor.newInstance("asd", "asb");
assertEquals(swtch.invoke(instance, r1), "asd");
}
@Test
public void testSwitchAppend() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchAppend.jav");
var clazz = classFiles.get("SwitchAppend");
var listClass = classFiles.get("List");
var elemClass = classFiles.get("Elem");
var linkedElemClass = classFiles.get("LinkedElem");
var elemCtor = elemClass.getDeclaredConstructor(Object.class);
var listCtor = linkedElemClass.getDeclaredConstructor(Object.class, listClass);
var list1 = listCtor.newInstance("A", listCtor.newInstance("B", elemCtor.newInstance("C")));
var list2 = listCtor.newInstance("D", listCtor.newInstance("E", elemCtor.newInstance("F")));
var instance = clazz.getDeclaredConstructor().newInstance();
var appendMethod = clazz.getDeclaredMethod("append", linkedElemClass, listClass);
var res = appendMethod.invoke(instance, list2, list1);
var expected = listCtor.newInstance("D", listCtor.newInstance("E", listCtor.newInstance("F", listCtor.newInstance("A", listCtor.newInstance("B", elemCtor.newInstance("C"))))));
assertEquals(res, expected);
}
@Test
public void testSwitchRecordLiteral() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingLiteralStyle.jav");
var clazz = classFiles.get("SwitchOverload");
}
@Test
public void testSwitchCaseHeritageDetection() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchCaseHeritageDetection.jav");
var clazz = classFiles.get("SwitchCaseHeritageDetection");
var clazzAbst = classFiles.get("NumberOrText");
var clazzStringer = classFiles.get("Text");
var clazzNumber = classFiles.get("Number");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var record = classFiles.get("Cons");
var ctor = record.getDeclaredConstructor(Integer.class, clazzAbst.getConstructor().newInstance().getClass());
var r1 = ctor.newInstance(1, clazzStringer.getConstructor().newInstance());
var r2 = ctor.newInstance(1, clazzNumber.getConstructor().newInstance());
assertEquals(swtch.invoke(instance, r1), "Second Element is a Text");
assertEquals(swtch.invoke(instance, r2), "Second Element is a Number");
}
@Test
public void testSwitchListRecord() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchRecordList.jav");
var clazz = classFiles.get("SwitchCaseHeritageDetection");
var instance = clazz.getDeclaredConstructor().newInstance();
var swtch = clazz.getDeclaredMethod("main", Object.class);
var linkedElem = classFiles.get("LinkedElem");
var listInterface = classFiles.get("List");
var elem = classFiles.get("Elem");
var constructorLinkedElem = linkedElem.getDeclaredConstructor(Integer.class, listInterface);
var constructorElem = elem.getDeclaredConstructor(Integer.class);
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 11);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(swtch.invoke(instance, listWithOneElement), 10);
}
@Test
public void testSwitchNestedValue() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchNestedValue.jav");
var clazz = classFiles.get("SwitchNestedValue");
var rec = classFiles.get("R");
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("main", rec);
var ctor = rec.getDeclaredConstructor(Integer.class);
var r1 = ctor.newInstance(10);
var r2 = ctor.newInstance(20);
var r3 = ctor.newInstance(30);
assertEquals(m.invoke(instance, r1), 1);
assertEquals(m.invoke(instance, r2), 2);
assertEquals(m.invoke(instance, r3), 3);
}
@Test
public void testGenericRecordSwitchCase() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "GenericRecordSwitchCase.jav");
var clazz = classFiles.get("GenericRecordSwitchCase");
var instance = clazz.getDeclaredConstructor().newInstance();
var linkedElem = classFiles.get("LinkedElem");
var listInterface = classFiles.get("List");
var elem = classFiles.get("Elem");
var swtch = clazz.getDeclaredMethod("main", linkedElem);
var constructorLinkedElem = linkedElem.getConstructor(Object.class, listInterface);
var constructorElem = elem.getConstructor(Object.class);
var listWithMoreThanOneElement = constructorLinkedElem.newInstance(5, constructorLinkedElem.newInstance(1, constructorElem.newInstance(5)));
assertEquals(swtch.invoke(instance, listWithMoreThanOneElement), 5);
var listWithOneElement = constructorLinkedElem.newInstance(5, constructorElem.newInstance(5));
assertEquals(swtch.invoke(instance, listWithOneElement), 5);
}
@Ignore("Not implemented") @Ignore("Not implemented")
@Test @Test
public void testSwitch2() throws Exception { public void testSwitch2() throws Exception {
@ -856,6 +706,7 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
} }
@Ignore("Not implemented")
@Test @Test
public void testOverloadPattern() throws Exception { public void testOverloadPattern() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav");
@ -863,101 +714,12 @@ public class TestComplete {
var rec = classFiles.get("Point"); var rec = classFiles.get("Point");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m1 = clazz.getDeclaredMethod("m", rec, rec); var m1 = clazz.getDeclaredMethod("m", rec);
var m2 = clazz.getDeclaredMethod("m", rec); var m2 = clazz.getDeclaredMethod("m", Integer.class);
var m3 = clazz.getDeclaredMethod("m", Integer.class);
var ptInt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1, 2); var pt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(10, 20);
var ptFlt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1f, 2f); assertEquals(m1.invoke(instance, pt), 30);
assertEquals(m2.invoke(instance, 10), 10);
assertEquals(m1.invoke(instance, ptInt, ptFlt), 1);
assertEquals(m1.invoke(instance, ptInt, ptInt), 2);
assertEquals(m1.invoke(instance, ptFlt, ptInt), 3);
assertEquals(m1.invoke(instance, ptFlt, ptFlt), 4);
assertEquals(m2.invoke(instance, ptInt), 5);
assertEquals(m2.invoke(instance, ptFlt), 6);
assertEquals(m3.invoke(instance, 10), 10);
}
@Test
public void testOverloadNestedPattern() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadNestedPattern.jav");
var clazz = classFiles.get("OverloadNestedPattern");
var rec = classFiles.get("R");
var instance = clazz.getDeclaredConstructor().newInstance();
var ctor = rec.getDeclaredConstructor(Object.class);
var r1 = ctor.newInstance(1);
var r2 = ctor.newInstance(r1);
var m = clazz.getDeclaredMethod("m", rec, rec);
assertEquals(m.invoke(instance, r2, r1), 1);
var r3 = ctor.newInstance(2f);
var r4 = ctor.newInstance(r3);
assertEquals(m.invoke(instance, r4, r3), 2);
assertEquals(m.invoke(instance, r1, r1), 3);
}
//@Ignore("Not implemented")
@Test
public void testPatternMatchingHaskellStyle() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav");
var clazz = classFiles.get("PatternMatchingHaskellStyle");
var R2 = classFiles.get("Elem");
var R = classFiles.get("LinkedElem");
var I = classFiles.get("List");
var rctor = R.getDeclaredConstructor(Object.class, I);
var r2ctor = R2.getDeclaredConstructor(Object.class);
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("append$LLinkedElem$_$LTPH$_$LLinkedElem$_$LTPH$_$", R, Object.class);
var x = rctor.newInstance(rctor.newInstance(0, rctor.newInstance(0, r2ctor.newInstance(0))), r2ctor.newInstance(0));
var y = rctor.newInstance(r2ctor.newInstance(0), r2ctor.newInstance(0));
assertEquals(m.invoke(instance, x, y), null);
assertEquals(m.invoke(instance, y, y), null);
}
@Test
public void testPatternMatchingListAppend() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingListAppend.jav");
var clazz = classFiles.get("PatternMatchingListAppend");
var instance = clazz.getDeclaredConstructor().newInstance();
var Cons = classFiles.get("Cons");
var Empty = classFiles.get("Empty");
var List = classFiles.get("List");
var ConsCtor = Cons.getDeclaredConstructor(Object.class, List);
var EmptyCtor = Empty.getDeclaredConstructor();
var list1 = ConsCtor.newInstance(1, ConsCtor.newInstance(2, ConsCtor.newInstance(3, EmptyCtor.newInstance())));
var list2 = ConsCtor.newInstance(4, ConsCtor.newInstance(5, ConsCtor.newInstance(6, EmptyCtor.newInstance())));
}
@Test
public void testOverloadSwitch() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchOverload.jav");
var clazz = classFiles.get("SwitchOverload");
var R = classFiles.get("R");
var rctor = R.getDeclaredConstructor(Number.class);
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m", R, Integer.class);
var x = rctor.newInstance(10);
var d = rctor.newInstance(20.0);
assertEquals(m.invoke(instance, x, 0), 50);
assertEquals(m.invoke(instance, d, 0), 40.0);
} }
@Test @Test
@ -966,7 +728,6 @@ public class TestComplete {
var clazz = classFiles.get("Interfaces"); var clazz = classFiles.get("Interfaces");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
} }
@Test @Test
public void testStatic() throws Exception { public void testStatic() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
@ -992,7 +753,7 @@ public class TestComplete {
var m = clazz.getDeclaredMethod("m"); var m = clazz.getDeclaredMethod("m");
assertEquals(m.invoke(instance), 6); assertEquals(m.invoke(instance), 6);
} }
@Test @Test
public void testLambdaRunnable() throws Exception { public void testLambdaRunnable() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "LambdaRunnable.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "LambdaRunnable.jav");
@ -1166,7 +927,7 @@ public class TestComplete {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "While.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "While.jav");
var clazz = classFiles.get("While"); var clazz = classFiles.get("While");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
assertEquals(clazz.getDeclaredMethod("m", Integer.class).invoke(instance, 5), 5); assertEquals(clazz.getDeclaredMethod("m", Integer.class).invoke(instance, 5), 5);
assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 10); assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 10);
} }
@ -1177,15 +938,6 @@ public class TestComplete {
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
} }
@Test
public void testAssign() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Assign.jav");
var clazz = classFiles.get("Assign");
var instance = clazz.getDeclaredConstructor().newInstance();
var m = clazz.getDeclaredMethod("m");
assertEquals(m.invoke(instance), 20);
}
@Test @Test
public void testBug122() throws Exception { public void testBug122() throws Exception {
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav"); var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");

View File

@ -220,19 +220,19 @@ public class TestCodegen {
public void testClassicSwitch() throws Exception { public void testClassicSwitch() throws Exception {
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC , new JavaClassName("SwitchClassic")); var targetClass = new TargetClass(Opcodes.ACC_PUBLIC , new JavaClassName("SwitchClassic"));
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchClassic", List.of(new MethodParameter(TargetType.Integer, "i")), TargetType.Integer, new TargetBlock(List.of( targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchClassic", List.of(new MethodParameter(TargetType.Integer, "i")), TargetType.Integer, new TargetBlock(List.of(
new TargetVarDecl(TargetType.Integer, "res", null), new TargetVarDecl(TargetType.Integer, "res", null),
new TargetSwitch(new TargetLocalVar(TargetType.Integer, "i"), List.of( new TargetSwitch(new TargetLocalVar(TargetType.Integer, "i"), List.of(
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(10)), new TargetBlock( new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(10)), new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(0)), new TargetBreak()) List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(0)), new TargetBreak())
)), )),
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(15), new TargetLiteral.IntLiteral(20)), new TargetBlock(List.of())), new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(15), new TargetLiteral.IntLiteral(20)), new TargetBlock(List.of())),
new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(30)), new TargetBlock( new TargetSwitch.Case(List.of(new TargetLiteral.IntLiteral(30)), new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(1)), new TargetBreak()) List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(1)), new TargetBreak())
)) ))
), new TargetSwitch.Case(new TargetBlock( ), new TargetSwitch.Case(new TargetBlock(
List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(2)), new TargetBreak()) List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "res"), new TargetLiteral.IntLiteral(2)), new TargetBreak())
), false)), ), false)),
new TargetReturn(new TargetLocalVar(TargetType.Integer, "res")) new TargetReturn(new TargetLocalVar(TargetType.Integer, "res"))
))); )));
var clazz = generateClass(targetClass, new ByteArrayClassLoader()); var clazz = generateClass(targetClass, new ByteArrayClassLoader());
@ -248,22 +248,22 @@ public class TestCodegen {
public void testTypeSwitch() throws Exception { public void testTypeSwitch() throws Exception {
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("SwitchEnhanced")); var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("SwitchEnhanced"));
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchType", List.of(new MethodParameter(TargetType.Object, "obj")), TargetType.Integer, new TargetBlock(List.of( targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchType", List.of(new MethodParameter(TargetType.Object, "obj")), TargetType.Integer, new TargetBlock(List.of(
new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of( new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of(
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.String, "aString")), new TargetBlock( new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.String, "aString")), new TargetBlock(
List.of(new TargetYield(new TargetLiteral.IntLiteral(0))) List.of(new TargetYield(new TargetLiteral.IntLiteral(0)))
), false), ), false),
new TargetSwitch.Case(List.of( new TargetSwitch.Case(List.of(
new TargetGuard(new TargetTypePattern(TargetType.Integer, "i"), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10))) new TargetGuard(new TargetTypePattern(TargetType.Integer, "i"), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)))
), new TargetBlock( ), new TargetBlock(
List.of(new TargetLiteral.IntLiteral(3)) List.of(new TargetLiteral.IntLiteral(3))
), true), ), true),
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.Integer, "anInteger")), new TargetBlock( new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.Integer, "anInteger")), new TargetBlock(
List.of(new TargetLiteral.IntLiteral(1)) List.of(new TargetLiteral.IntLiteral(1))
), true) ), true)
), new TargetSwitch.Case(new TargetBlock( ), new TargetSwitch.Case(new TargetBlock(
List.of(new TargetLiteral.IntLiteral(2)) List.of(new TargetLiteral.IntLiteral(2))
), true), TargetType.Integer) ), true), TargetType.Integer)
)))); ))));
var clazz = generateClass(targetClass, new ByteArrayClassLoader()); var clazz = generateClass(targetClass, new ByteArrayClassLoader());
var m = clazz.getDeclaredMethod("switchType", Object.class); var m = clazz.getDeclaredMethod("switchType", Object.class);
assertEquals(m.invoke(null, "String"), 0); assertEquals(m.invoke(null, "String"), 0);