1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added support for #pragma code_seg() and #pragma data_seg(). #113

This commit is contained in:
jespergravgaard 2019-08-09 22:38:33 +02:00
parent 6b0ef4408c
commit dbb6ce5933
52 changed files with 2973 additions and 1699 deletions

View File

@ -289,7 +289,6 @@ public interface ProgramValue {
@Override
public void set(Value value) {
statementKickAsm.getUses().set(idx, (SymbolVariableRef) value);
}
}
@ -903,4 +902,25 @@ public interface ProgramValue {
}
}
/** Uses inside a constant array initialized using inline kickasm. */
class ProgramValueConstantArrayKickAsmUses implements ProgramValue {
private final ConstantArrayKickAsm constantArrayKickAsm;
private final int idx;
public ProgramValueConstantArrayKickAsmUses(ConstantArrayKickAsm constantArrayKickAsm, int idx) {
this.constantArrayKickAsm = constantArrayKickAsm;
this.idx = idx;
}
@Override
public Value get() {
return constantArrayKickAsm.getUses().get(idx);
}
@Override
public void set(Value value) {
constantArrayKickAsm.getUses().set(idx, (SymbolVariableRef) value);
}
}
}

View File

@ -145,7 +145,7 @@ public class ProgramValueIterator {
if(cycles!=null) {
execute(new ProgramValue.ProgramValueKickAsmCycles(statementKickAsm), handler, statement, statementsIt, block);
}
List<SymbolVariableRef> uses = statementKickAsm.getUses();
List<SymbolRef> uses = statementKickAsm.getUses();
for(int i = 0; i < uses.size(); i++) {
execute(new ProgramValue.KickAsmUses(statementKickAsm, i), handler, statement, statementsIt, block);
}
@ -226,6 +226,12 @@ public class ProgramValueIterator {
subValues.add(new ProgramValue.ProgramValueArrayFilledSize((ArrayFilled) value));
} else if(value instanceof ConstantArrayFilled) {
subValues.add(new ProgramValue.ProgramValueConstantArrayFilledSize((ConstantArrayFilled) value));
} else if(value instanceof ConstantArrayKickAsm) {
ConstantArrayKickAsm constantArrayKickAsm = (ConstantArrayKickAsm) value;
List<SymbolRef> uses = constantArrayKickAsm.getUses();
for(int i = 0; i < uses.size(); i++) {
subValues.add(new ProgramValue.ProgramValueConstantArrayKickAsmUses(constantArrayKickAsm, i));
}
} else if(value instanceof LvalueIntermediate) {
subValues.add(new ProgramValue.ProgramValueLValueIntermediateVariable((LvalueIntermediate) value));
} else if(value == null ||
@ -236,7 +242,6 @@ public class ProgramValueIterator {
value instanceof ConstantLiteral ||
value instanceof ConstantRef ||
value instanceof StructZero ||
value instanceof ConstantArrayKickAsm ||
value instanceof LabelRef
) {
// No sub values

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -39,7 +40,7 @@ public class OperatorSizeOf extends OperatorUnary {
if(typeSizeConstant == null) {
// Constant not found - create it
long typeSize = type.getSizeBytes();
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize&0xff, SymbolType.BYTE));
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(typeSizeConstant);
}
return typeSizeConstant.getRef();

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.operators;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
@ -41,7 +42,7 @@ public class OperatorTypeId extends OperatorUnary {
if(typeIdConstant == null) {
// Constant not found - create it
long typeSize = getTypeId(type);
typeIdConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize));
typeIdConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(typeIdConstant);
}
return typeIdConstant.getRef();

View File

@ -4,6 +4,7 @@ import dk.camelot64.kickc.asm.AsmClobber;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.SymbolRef;
import dk.camelot64.kickc.model.values.SymbolVariableRef;
import java.util.ArrayList;
@ -25,7 +26,7 @@ public class StatementKickAsm extends StatementBase {
private RValue cycles;
/** Variables/constants used by the kickasm code. */
private List<SymbolVariableRef> uses;
private List<SymbolRef> uses;
/** Declared clobber for the inline kick-assembler . */
private AsmClobber declaredClobber;
@ -36,7 +37,7 @@ public class StatementKickAsm extends StatementBase {
this.uses = new ArrayList<>();
}
public StatementKickAsm(String kickAsmCode, RValue location, RValue bytes, RValue cycles, List<SymbolVariableRef> uses, AsmClobber declaredClobber, StatementSource source, List<Comment> comments) {
public StatementKickAsm(String kickAsmCode, RValue location, RValue bytes, RValue cycles, List<SymbolRef> uses, AsmClobber declaredClobber, StatementSource source, List<Comment> comments) {
super(null, source, comments);
this.kickAsmCode = kickAsmCode;
this.location = location;
@ -62,11 +63,11 @@ public class StatementKickAsm extends StatementBase {
this.location = location;
}
public List<SymbolVariableRef> getUses() {
public List<SymbolRef> getUses() {
return uses;
}
public void setUses(List<SymbolVariableRef> uses) {
public void setUses(List<SymbolRef> uses) {
this.uses = uses;
}
@ -78,7 +79,7 @@ public class StatementKickAsm extends StatementBase {
txt.append("location ");
txt.append(location.toString(program));
}
for(SymbolVariableRef use : uses) {
for(SymbolRef use : uses) {
txt.append(" uses ");
txt.append(use.getFullName());
}
@ -109,7 +110,7 @@ public class StatementKickAsm extends StatementBase {
return cycles;
}
public void addUses(SymbolVariableRef symbolVariableRef) {
public void addUses(SymbolRef symbolVariableRef) {
uses.add(symbolVariableRef);
}
}

View File

@ -10,7 +10,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeBlockScope;
public class BlockScope extends Scope {
public BlockScope(String name, Scope parentScope) {
super(name, parentScope);
super(name, parentScope, parentScope.getSegmentData());
}
@Override

View File

@ -11,8 +11,8 @@ public class ConstantVar extends SymbolVariable {
/** The constant value. */
private ConstantValue value;
public ConstantVar(String name, Scope scope, SymbolType type, ConstantValue value) {
super(name, scope, type);
public ConstantVar(String name, Scope scope, SymbolType type, ConstantValue value, String dataSegment) {
super(name, scope, type, dataSegment);
this.value = value;
}

View File

@ -8,7 +8,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeEnum;
public class EnumDefinition extends Scope {
public EnumDefinition(String name, Scope parentScope) {
super(name, parentScope);
super(name, parentScope, parentScope.getSegmentData());
}
@Override

View File

@ -12,7 +12,8 @@ import java.util.List;
/** Symbol describing a procedure/function */
public class Procedure extends Scope {
/** The return type. {@link SymbolType#VOID} if the procedure does not return a value. */
/** The return type. {@link SymbolType#VOID} if the procedure does not return a value. */
private final SymbolType returnType;
/** The names of the parameters of the procedure. */
private List<String> parameterNames;
@ -24,13 +25,20 @@ public class Procedure extends Scope {
private List<Comment> comments;
/** Reserved zeropage addresses. */
private List<Number> reservedZps;
/** The code segment to put the procedure into. */
private String codeSegment;
public Procedure(String name, SymbolType returnType, Scope parentScope) {
super(name, parentScope);
public Procedure(String name, SymbolType returnType, Scope parentScope, String codeSegment, String dataSegment) {
super(name, parentScope, dataSegment);
this.returnType = returnType;
this.declaredInline = false;
this.interruptType = null;
this.comments = new ArrayList<>();
this.codeSegment = codeSegment;
}
public String getCodeSegment() {
return codeSegment;
}
public List<String> getParameterNames() {
@ -109,6 +117,7 @@ public class Procedure extends Scope {
/**
* Sets any zero-page addresses reserved by the procedure. The KickC-compiler is not allowed to use these addresses.
*
* @return reserved addresses
*/
public List<Number> getReservedZps() {
@ -117,6 +126,7 @@ public class Procedure extends Scope {
/**
* Gets any reserved zero-page addresses that the compiler is not allowed to use.
*
* @param reservedZp reserved addresses
*/
public void setReservedZps(List<Number> reservedZps) {
@ -134,8 +144,7 @@ public class Procedure extends Scope {
/** Interrupt served directly from hardware through $fffe-f. Will exit through RTI and will save ALL registers. */
HARDWARE_ALL,
/** Interrupt served directly from hardware through $fffe-f. Will exit through RTI and will save necessary registers based on clobber. */
HARDWARE_CLOBBER
;
HARDWARE_CLOBBER;
/** The default interrupt type if none is explicitly declared (KERNEL_MIN). */
public static InterruptType DEFAULT = InterruptType.KERNEL_MIN;
@ -154,8 +163,8 @@ public class Procedure extends Scope {
if(declaredInline) {
res.append("inline ");
}
if(interruptType !=null) {
res.append("interrupt("+ interruptType +")");
if(interruptType != null) {
res.append("interrupt(" + interruptType + ")");
}
res.append("(" + getType().getTypeName() + ") ");
res.append(getFullName());

View File

@ -11,7 +11,7 @@ public class ProgramScope extends Scope {
public ProgramScope() {
super("", null);
super("", null, Scope.SEGMENT_DATA_DEFAULT);
}
@Override

View File

@ -15,6 +15,11 @@ import java.util.*;
*/
public abstract class Scope implements Symbol, Serializable {
/** The default code segment. */
public static final String SEGMENT_CODE_DEFAULT = "Code";
/** The default data segment. */
public static final String SEGMENT_DATA_DEFAULT = "Data";
private String name;
private HashMap<String, Symbol> symbols;
private int intermediateVarCount = 0;
@ -22,18 +27,13 @@ public abstract class Scope implements Symbol, Serializable {
private int blockCount = 1;
private Scope parentScope;
private String fullName;
private String segmentData;
public Scope(String name, Scope parentScope) {
public Scope(String name, Scope parentScope, String segmentData) {
this.name = name;
this.parentScope = parentScope;
this.symbols = new LinkedHashMap<>();
setFullName();
}
public Scope() {
this.name = "";
this.parentScope = null;
this.symbols = new LinkedHashMap<>();
this.segmentData = segmentData;
setFullName();
}
@ -42,6 +42,10 @@ public abstract class Scope implements Symbol, Serializable {
fullName = (scopeName.length() > 0) ? scopeName + "::" + name : name;
}
public String getSegmentData() {
return segmentData;
}
public HashMap<String, Symbol> getSymbols() {
return symbols;
}
@ -95,13 +99,13 @@ public abstract class Scope implements Symbol, Serializable {
symbols.remove(symbol.getLocalName());
}
public VariableUnversioned addVariable(String name, SymbolType type) {
return add(new VariableUnversioned(name, this, type));
public VariableUnversioned addVariable(String name, SymbolType type, String dataSegment) {
return add(new VariableUnversioned(name, this, type, dataSegment));
}
public VariableIntermediate addVariableIntermediate() {
String name = allocateIntermediateVariableName();
return add(new VariableIntermediate(name, this, SymbolType.VAR));
return add(new VariableIntermediate(name, this, SymbolType.VAR, getSegmentData()));
}
/**
@ -276,8 +280,8 @@ public abstract class Scope implements Symbol, Serializable {
return (BlockScope) getSymbol(name);
}
public Procedure addProcedure(String name, SymbolType type) {
return add(new Procedure(name, type, this));
public Procedure addProcedure(String name, SymbolType type, String codeSegment, String dataSegment) {
return add(new Procedure(name, type, this, codeSegment, dataSegment));
}
public Procedure getProcedure(String name) {

View File

@ -10,7 +10,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeStruct;
public class StructDefinition extends Scope {
public StructDefinition(String name, Scope parentScope) {
super(name, parentScope);
super(name, parentScope, SEGMENT_DATA_DEFAULT);
}
@Override

View File

@ -47,12 +47,16 @@ public abstract class SymbolVariable implements Symbol {
/** Full name of variable (scope::name or name) */
private String fullName;
public SymbolVariable(String name, Scope scope, SymbolType type) {
/** The data segment to put the variable into (if it is allocated in memory). */
private String dataSegment;
public SymbolVariable(String name, Scope scope, SymbolType type, String dataSegment) {
this.name = name;
this.scope = scope;
this.type = type;
this.inferredType = false;
this.comments = new ArrayList<>();
this.dataSegment = dataSegment;
setFullName();
}
@ -61,6 +65,10 @@ public abstract class SymbolVariable implements Symbol {
fullName = (scopeName.length() > 0) ? scopeName + "::" + name : name;
}
public String getDataSegment() {
return dataSegment;
}
@Override
public String getLocalName() {
return name;

View File

@ -7,7 +7,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeTypeDefScope;
public class TypeDefsScope extends Scope {
public TypeDefsScope(String name, Scope parentScope) {
super(name, parentScope);
super(name, parentScope, parentScope.getSegmentData());
}
@Override

View File

@ -10,8 +10,8 @@ public abstract class Variable extends SymbolVariable {
/** If the variable is assigned to an ASM register, this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */
private Registers.Register allocation;
public Variable(String name, Scope scope, SymbolType type) {
super(name, scope, type);
public Variable(String name, Scope scope, SymbolType type, String dataSegment) {
super(name, scope, type, dataSegment);
}
public Registers.Register getAllocation() {

View File

@ -7,8 +7,8 @@ import dk.camelot64.kickc.model.types.SymbolType;
*/
public class VariableIntermediate extends Variable {
public VariableIntermediate(String name, Scope scope, SymbolType type) {
super(name, scope, type);
public VariableIntermediate(String name, Scope scope, SymbolType type, String dataSegment) {
super(name, scope, type, dataSegment);
}
@Override

View File

@ -10,11 +10,8 @@ public class VariableUnversioned extends Variable {
/** The number of the next version */
private Integer nextVersionNumber;
public VariableUnversioned(
String name,
Scope scope,
SymbolType type) {
super(name, scope, type);
public VariableUnversioned( String name, Scope scope, SymbolType type, String dataSegment) {
super(name, scope, type, dataSegment);
this.nextVersionNumber = 0;
}

View File

@ -8,7 +8,7 @@ public class VariableVersion extends Variable {
private String versionOfName;
public VariableVersion(VariableUnversioned versionOf, int version) {
super(versionOf.getLocalName() + "#" + version, versionOf.getScope(), versionOf.getType());
super(versionOf.getLocalName() + "#" + version, versionOf.getScope(), versionOf.getType(), versionOf.getDataSegment());
this.setDeclaredAlignment(versionOf.getDeclaredAlignment());
this.setDeclaredRegister(versionOf.getDeclaredRegister());
this.setDeclaredVolatile(versionOf.isDeclaredVolatile());
@ -22,7 +22,7 @@ public class VariableVersion extends Variable {
String name,
SymbolType type,
String versionOfName) {
super(name, null, type);
super(name, null, type, Scope.SEGMENT_DATA_DEFAULT);
this.versionOfName = versionOfName;
}

View File

@ -19,9 +19,21 @@ public class ConstantArrayKickAsm implements ConstantArray {
/** KickAssembler code generating the data. */
private String kickAsmCode;
public ConstantArrayKickAsm(SymbolType elementType, String kickAsmCode) {
/** Variables/constants used by the kickasm code. */
private List<SymbolRef> uses;
public ConstantArrayKickAsm(SymbolType elementType, String kickAsmCode, List<SymbolRef> uses) {
this.elementType = elementType;
this.kickAsmCode = kickAsmCode;
this.uses = uses;
}
public List<SymbolRef> getUses() {
return uses;
}
public void setUses(List<SymbolRef> uses) {
this.uses = uses;
}
@Override
@ -54,7 +66,16 @@ public class ConstantArrayKickAsm implements ConstantArray {
@Override
public String toString(Program program) {
StringBuilder txt = new StringBuilder();
txt.append("kickasm {{ ");
txt.append("kickasm");
if(uses.size()>0) {
txt.append("( ");
for(SymbolRef use : uses) {
txt.append(" uses ");
txt.append(use.getFullName());
}
txt.append(")");
}
txt.append(" {{ ");
txt.append(kickAsmCode);
txt.append(" }}");
return txt.toString();

View File

@ -69,7 +69,9 @@ globalDirective
: ('#pragma' 'reserve'|'#reserve') '(' NUMBER ( ',' NUMBER )* ')' #globalDirectiveReserve
| ('#pragma' 'pc'|'#pc') '(' NUMBER ')' #globalDirectivePc
| ('#pragma' 'target'|'#target') '(' NAME ')' #globalDirectivePlatform
| ('#pragma' 'link'|'#link') '(' STRING ')' #globalDirectiveLinkScript
| ('#pragma' 'link') '(' STRING ')' #globalDirectiveLinkScript
| ('#pragma' 'code_seg') '(' NAME ')' #globalDirectiveCodeSeg
| ('#pragma' 'data_seg') '(' NAME ')' #globalDirectiveDataSeg
| ('#pragma' 'encoding'|'#encoding') '(' NAME')' #globalDirectiveEncoding
;

View File

@ -87,26 +87,27 @@ T__85=86
T__86=87
T__87=88
T__88=89
MNEMONIC=90
KICKASM=91
SIMPLETYPE=92
STRING=93
CHAR=94
BOOLEAN=95
NUMBER=96
NUMFLOAT=97
BINFLOAT=98
DECFLOAT=99
HEXFLOAT=100
NUMINT=101
BININTEGER=102
DECINTEGER=103
HEXINTEGER=104
NAME=105
ASMREL=106
WS=107
COMMENT_LINE=108
COMMENT_BLOCK=109
T__89=90
MNEMONIC=91
KICKASM=92
SIMPLETYPE=93
STRING=94
CHAR=95
BOOLEAN=96
NUMBER=97
NUMFLOAT=98
BINFLOAT=99
DECFLOAT=100
HEXFLOAT=101
NUMINT=102
BININTEGER=103
DECINTEGER=104
HEXINTEGER=105
NAME=106
ASMREL=107
WS=108
COMMENT_LINE=109
COMMENT_BLOCK=110
'import'=1
';'=2
'typedef'=3
@ -124,75 +125,76 @@ COMMENT_BLOCK=109
'target'=15
'#target'=16
'link'=17
'#link'=18
'encoding'=19
'#encoding'=20
'const'=21
'extern'=22
'align'=23
'register'=24
'inline'=25
'volatile'=26
'interrupt'=27
'if'=28
'else'=29
'while'=30
'do'=31
'for'=32
'return'=33
'break'=34
'continue'=35
'asm'=36
':'=37
'..'=38
'signed'=39
'unsigned'=40
'*'=41
'['=42
']'=43
'struct'=44
'enum'=45
'.'=46
'->'=47
'sizeof'=48
'typeid'=49
'--'=50
'++'=51
'+'=52
'-'=53
'!'=54
'&'=55
'~'=56
'>>'=57
'<<'=58
'/'=59
'%'=60
'<'=61
'>'=62
'=='=63
'!='=64
'<='=65
'>='=66
'^'=67
'|'=68
'&&'=69
'||'=70
'?'=71
'+='=72
'-='=73
'*='=74
'/='=75
'%='=76
'<<='=77
'>>='=78
'&='=79
'|='=80
'^='=81
'kickasm'=82
'resource'=83
'uses'=84
'clobbers'=85
'bytes'=86
'cycles'=87
'.byte'=88
'#'=89
'code_seg'=18
'data_seg'=19
'encoding'=20
'#encoding'=21
'const'=22
'extern'=23
'align'=24
'register'=25
'inline'=26
'volatile'=27
'interrupt'=28
'if'=29
'else'=30
'while'=31
'do'=32
'for'=33
'return'=34
'break'=35
'continue'=36
'asm'=37
':'=38
'..'=39
'signed'=40
'unsigned'=41
'*'=42
'['=43
']'=44
'struct'=45
'enum'=46
'.'=47
'->'=48
'sizeof'=49
'typeid'=50
'--'=51
'++'=52
'+'=53
'-'=54
'!'=55
'&'=56
'~'=57
'>>'=58
'<<'=59
'/'=60
'%'=61
'<'=62
'>'=63
'=='=64
'!='=65
'<='=66
'>='=67
'^'=68
'|'=69
'&&'=70
'||'=71
'?'=72
'+='=73
'-='=74
'*='=75
'/='=76
'%='=77
'<<='=78
'>>='=79
'&='=80
'|='=81
'^='=82
'kickasm'=83
'resource'=84
'uses'=85
'clobbers'=86
'bytes'=87
'cycles'=88
'.byte'=89
'#'=90

View File

@ -1,4 +1,4 @@
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7.2
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
package dk.camelot64.kickc.parser;
import org.antlr.v4.runtime.ParserRuleContext;
@ -251,6 +251,30 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -1,4 +1,4 @@
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7.2
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
package dk.camelot64.kickc.parser;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
@ -151,6 +151,20 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -1,4 +1,4 @@
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7.2
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
package dk.camelot64.kickc.parser;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
@ -11,7 +11,7 @@ import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class KickCLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.7.2", RuntimeMetaData.VERSION); }
static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
@ -29,10 +29,10 @@ public class KickCLexer extends Lexer {
T__66=67, T__67=68, T__68=69, T__69=70, T__70=71, T__71=72, T__72=73,
T__73=74, T__74=75, T__75=76, T__76=77, T__77=78, T__78=79, T__79=80,
T__80=81, T__81=82, T__82=83, T__83=84, T__84=85, T__85=86, T__86=87,
T__87=88, T__88=89, MNEMONIC=90, KICKASM=91, SIMPLETYPE=92, STRING=93,
CHAR=94, BOOLEAN=95, NUMBER=96, NUMFLOAT=97, BINFLOAT=98, DECFLOAT=99,
HEXFLOAT=100, NUMINT=101, BININTEGER=102, DECINTEGER=103, HEXINTEGER=104,
NAME=105, ASMREL=106, WS=107, COMMENT_LINE=108, COMMENT_BLOCK=109;
T__87=88, T__88=89, T__89=90, MNEMONIC=91, KICKASM=92, SIMPLETYPE=93,
STRING=94, CHAR=95, BOOLEAN=96, NUMBER=97, NUMFLOAT=98, BINFLOAT=99, DECFLOAT=100,
HEXFLOAT=101, NUMINT=102, BININTEGER=103, DECINTEGER=104, HEXINTEGER=105,
NAME=106, ASMREL=107, WS=108, COMMENT_LINE=109, COMMENT_BLOCK=110;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
@ -41,60 +41,51 @@ public class KickCLexer extends Lexer {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24",
"T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32",
"T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40",
"T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48",
"T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56",
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72",
"T__73", "T__74", "T__75", "T__76", "T__77", "T__78", "T__79", "T__80",
"T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88",
"MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", "CHAR", "BOOLEAN", "NUMBER",
"NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
"DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME",
"NAME_START", "NAME_CHAR", "ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK"
};
}
public static final String[] ruleNames = makeRuleNames();
public static final String[] ruleNames = {
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24",
"T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32",
"T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40",
"T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48",
"T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56",
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72",
"T__73", "T__74", "T__75", "T__76", "T__77", "T__78", "T__79", "T__80",
"T__81", "T__82", "T__83", "T__84", "T__85", "T__86", "T__87", "T__88",
"T__89", "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", "CHAR", "BOOLEAN",
"NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER",
"DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME",
"NAME_START", "NAME_CHAR", "ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK"
};
private static String[] makeLiteralNames() {
return new String[] {
null, "'import'", "';'", "'typedef'", "','", "'='", "'('", "')'", "'{'",
"'}'", "'#pragma'", "'reserve'", "'#reserve'", "'pc'", "'#pc'", "'target'",
"'#target'", "'link'", "'#link'", "'encoding'", "'#encoding'", "'const'",
"'extern'", "'align'", "'register'", "'inline'", "'volatile'", "'interrupt'",
"'if'", "'else'", "'while'", "'do'", "'for'", "'return'", "'break'",
"'continue'", "'asm'", "':'", "'..'", "'signed'", "'unsigned'", "'*'",
"'['", "']'", "'struct'", "'enum'", "'.'", "'->'", "'sizeof'", "'typeid'",
"'--'", "'++'", "'+'", "'-'", "'!'", "'&'", "'~'", "'>>'", "'<<'", "'/'",
"'%'", "'<'", "'>'", "'=='", "'!='", "'<='", "'>='", "'^'", "'|'", "'&&'",
"'||'", "'?'", "'+='", "'-='", "'*='", "'/='", "'%='", "'<<='", "'>>='",
"'&='", "'|='", "'^='", "'kickasm'", "'resource'", "'uses'", "'clobbers'",
"'bytes'", "'cycles'", "'.byte'", "'#'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE",
"STRING", "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT",
"HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME",
"ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
private static final String[] _LITERAL_NAMES = {
null, "'import'", "';'", "'typedef'", "','", "'='", "'('", "')'", "'{'",
"'}'", "'#pragma'", "'reserve'", "'#reserve'", "'pc'", "'#pc'", "'target'",
"'#target'", "'link'", "'code_seg'", "'data_seg'", "'encoding'", "'#encoding'",
"'const'", "'extern'", "'align'", "'register'", "'inline'", "'volatile'",
"'interrupt'", "'if'", "'else'", "'while'", "'do'", "'for'", "'return'",
"'break'", "'continue'", "'asm'", "':'", "'..'", "'signed'", "'unsigned'",
"'*'", "'['", "']'", "'struct'", "'enum'", "'.'", "'->'", "'sizeof'",
"'typeid'", "'--'", "'++'", "'+'", "'-'", "'!'", "'&'", "'~'", "'>>'",
"'<<'", "'/'", "'%'", "'<'", "'>'", "'=='", "'!='", "'<='", "'>='", "'^'",
"'|'", "'&&'", "'||'", "'?'", "'+='", "'-='", "'*='", "'/='", "'%='",
"'<<='", "'>>='", "'&='", "'|='", "'^='", "'kickasm'", "'resource'", "'uses'",
"'clobbers'", "'bytes'", "'cycles'", "'.byte'", "'#'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE",
"STRING", "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT",
"HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME",
"ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
@ -153,7 +144,7 @@ public class KickCLexer extends Lexer {
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2o\u0458\b\1\4\2\t"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2p\u0466\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
@ -165,393 +156,400 @@ public class KickCLexer extends Lexer {
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\3\2\3\2\3\2\3\2\3\2"+
"\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3"+
"\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f"+
"\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16"+
"\3\16\3\16\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21"+
"\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\23\3\23"+
"\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25"+
"\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26"+
"\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30"+
"\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32"+
"\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34"+
"\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36\3\36\3\36"+
"\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3"+
"\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3"+
"%\3&\3&\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3)\3)\3)\3"+
"*\3*\3+\3+\3,\3,\3-\3-\3-\3-\3-\3-\3-\3.\3.\3.\3.\3.\3/\3/\3\60\3\60\3"+
"\60\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3"+
"\62\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\66\3\66\3\67\3\67\38\38"+
"\39\39\3:\3:\3:\3;\3;\3;\3<\3<\3=\3=\3>\3>\3?\3?\3@\3@\3@\3A\3A\3A\3B"+
"\3B\3B\3C\3C\3C\3D\3D\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3I\3I\3I\3J\3J\3J"+
"\3K\3K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q"+
"\3R\3R\3R\3S\3S\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3T\3T\3T\3U\3U\3U"+
"\3U\3U\3V\3V\3V\3V\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X"+
"\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3["+
"\3[\5[\u0359\n[\3\\\3\\\3\\\3\\\7\\\u035f\n\\\f\\\16\\\u0362\13\\\3\\"+
"\3\\\3\\\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3"+
"]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\5]\u038c\n]\3^\3^\3"+
"^\3^\7^\u0392\n^\f^\16^\u0395\13^\3^\3^\5^\u0399\n^\3^\3^\5^\u039d\n^"+
"\5^\u039f\n^\3^\5^\u03a2\n^\3_\3_\3_\3_\5_\u03a8\n_\3_\3_\3`\3`\3`\3`"+
"\3`\3`\3`\3`\3`\5`\u03b5\n`\3a\3a\5a\u03b9\na\3b\3b\3b\5b\u03be\nb\3c"+
"\3c\3c\3c\3c\5c\u03c5\nc\3c\7c\u03c8\nc\fc\16c\u03cb\13c\3c\3c\6c\u03cf"+
"\nc\rc\16c\u03d0\3d\7d\u03d4\nd\fd\16d\u03d7\13d\3d\3d\6d\u03db\nd\rd"+
"\16d\u03dc\3e\3e\3e\3e\3e\5e\u03e4\ne\3e\7e\u03e7\ne\fe\16e\u03ea\13e"+
"\3e\3e\6e\u03ee\ne\re\16e\u03ef\3f\3f\3f\5f\u03f5\nf\3f\3f\3f\5f\u03fa"+
"\nf\3g\3g\3g\6g\u03ff\ng\rg\16g\u0400\3g\3g\6g\u0405\ng\rg\16g\u0406\5"+
"g\u0409\ng\3h\6h\u040c\nh\rh\16h\u040d\3i\3i\3i\3i\3i\5i\u0415\ni\3i\6"+
"i\u0418\ni\ri\16i\u0419\3j\3j\3k\3k\3l\3l\3m\3m\7m\u0424\nm\fm\16m\u0427"+
"\13m\3n\3n\3o\3o\3p\3p\7p\u042f\np\fp\16p\u0432\13p\3p\6p\u0435\np\rp"+
"\16p\u0436\3q\6q\u043a\nq\rq\16q\u043b\3q\3q\3r\3r\3r\3r\7r\u0444\nr\f"+
"r\16r\u0447\13r\3r\3r\3s\3s\3s\3s\7s\u044f\ns\fs\16s\u0452\13s\3s\3s\3"+
"s\3s\3s\4\u0360\u0450\2t\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f"+
"\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63"+
"\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62"+
"c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087"+
"E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009b"+
"O\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00af"+
"Y\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3"+
"c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3\2\u00d5\2\u00d7"+
"\2\u00d9k\u00db\2\u00dd\2\u00dfl\u00e1m\u00e3n\u00e5o\3\2\22\3\2$$\3\2"+
"||\4\2rruu\4\2ooww\3\2))\4\2uuww\7\2dfkknnuuyy\4\2DDdd\3\2\62\63\3\2\62"+
";\5\2\62;CHch\5\2C\\aac|\6\2\62;C\\aac|\4\2--//\6\2\13\f\17\17\"\"\u00a2"+
"\u00a2\4\2\f\f\17\17\2\u04ca\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3"+
"\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2"+
"\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37"+
"\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3"+
"\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2"+
"\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C"+
"\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2"+
"\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2"+
"\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i"+
"\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2"+
"\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081"+
"\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2"+
"\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093"+
"\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2"+
"\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5"+
"\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2"+
"\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7"+
"\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2"+
"\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9"+
"\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2"+
"\2\2\u00d9\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5"+
"\3\2\2\2\3\u00e7\3\2\2\2\5\u00ee\3\2\2\2\7\u00f0\3\2\2\2\t\u00f8\3\2\2"+
"\2\13\u00fa\3\2\2\2\r\u00fc\3\2\2\2\17\u00fe\3\2\2\2\21\u0100\3\2\2\2"+
"\23\u0102\3\2\2\2\25\u0104\3\2\2\2\27\u010c\3\2\2\2\31\u0114\3\2\2\2\33"+
"\u011d\3\2\2\2\35\u0120\3\2\2\2\37\u0124\3\2\2\2!\u012b\3\2\2\2#\u0133"+
"\3\2\2\2%\u0138\3\2\2\2\'\u013e\3\2\2\2)\u0147\3\2\2\2+\u0151\3\2\2\2"+
"-\u0157\3\2\2\2/\u015e\3\2\2\2\61\u0164\3\2\2\2\63\u016d\3\2\2\2\65\u0174"+
"\3\2\2\2\67\u017d\3\2\2\29\u0187\3\2\2\2;\u018a\3\2\2\2=\u018f\3\2\2\2"+
"?\u0195\3\2\2\2A\u0198\3\2\2\2C\u019c\3\2\2\2E\u01a3\3\2\2\2G\u01a9\3"+
"\2\2\2I\u01b2\3\2\2\2K\u01b6\3\2\2\2M\u01b8\3\2\2\2O\u01bb\3\2\2\2Q\u01c2"+
"\3\2\2\2S\u01cb\3\2\2\2U\u01cd\3\2\2\2W\u01cf\3\2\2\2Y\u01d1\3\2\2\2["+
"\u01d8\3\2\2\2]\u01dd\3\2\2\2_\u01df\3\2\2\2a\u01e2\3\2\2\2c\u01e9\3\2"+
"\2\2e\u01f0\3\2\2\2g\u01f3\3\2\2\2i\u01f6\3\2\2\2k\u01f8\3\2\2\2m\u01fa"+
"\3\2\2\2o\u01fc\3\2\2\2q\u01fe\3\2\2\2s\u0200\3\2\2\2u\u0203\3\2\2\2w"+
"\u0206\3\2\2\2y\u0208\3\2\2\2{\u020a\3\2\2\2}\u020c\3\2\2\2\177\u020e"+
"\3\2\2\2\u0081\u0211\3\2\2\2\u0083\u0214\3\2\2\2\u0085\u0217\3\2\2\2\u0087"+
"\u021a\3\2\2\2\u0089\u021c\3\2\2\2\u008b\u021e\3\2\2\2\u008d\u0221\3\2"+
"\2\2\u008f\u0224\3\2\2\2\u0091\u0226\3\2\2\2\u0093\u0229\3\2\2\2\u0095"+
"\u022c\3\2\2\2\u0097\u022f\3\2\2\2\u0099\u0232\3\2\2\2\u009b\u0235\3\2"+
"\2\2\u009d\u0239\3\2\2\2\u009f\u023d\3\2\2\2\u00a1\u0240\3\2\2\2\u00a3"+
"\u0243\3\2\2\2\u00a5\u0246\3\2\2\2\u00a7\u024e\3\2\2\2\u00a9\u0257\3\2"+
"\2\2\u00ab\u025c\3\2\2\2\u00ad\u0265\3\2\2\2\u00af\u026b\3\2\2\2\u00b1"+
"\u0272\3\2\2\2\u00b3\u0278\3\2\2\2\u00b5\u0358\3\2\2\2\u00b7\u035a\3\2"+
"\2\2\u00b9\u038b\3\2\2\2\u00bb\u038d\3\2\2\2\u00bd\u03a3\3\2\2\2\u00bf"+
"\u03b4\3\2\2\2\u00c1\u03b8\3\2\2\2\u00c3\u03bd\3\2\2\2\u00c5\u03c4\3\2"+
"\2\2\u00c7\u03d5\3\2\2\2\u00c9\u03e3\3\2\2\2\u00cb\u03f4\3\2\2\2\u00cd"+
"\u0408\3\2\2\2\u00cf\u040b\3\2\2\2\u00d1\u0414\3\2\2\2\u00d3\u041b\3\2"+
"\2\2\u00d5\u041d\3\2\2\2\u00d7\u041f\3\2\2\2\u00d9\u0421\3\2\2\2\u00db"+
"\u0428\3\2\2\2\u00dd\u042a\3\2\2\2\u00df\u042c\3\2\2\2\u00e1\u0439\3\2"+
"\2\2\u00e3\u043f\3\2\2\2\u00e5\u044a\3\2\2\2\u00e7\u00e8\7k\2\2\u00e8"+
"\u00e9\7o\2\2\u00e9\u00ea\7r\2\2\u00ea\u00eb\7q\2\2\u00eb\u00ec\7t\2\2"+
"\u00ec\u00ed\7v\2\2\u00ed\4\3\2\2\2\u00ee\u00ef\7=\2\2\u00ef\6\3\2\2\2"+
"\u00f0\u00f1\7v\2\2\u00f1\u00f2\7{\2\2\u00f2\u00f3\7r\2\2\u00f3\u00f4"+
"\7g\2\2\u00f4\u00f5\7f\2\2\u00f5\u00f6\7g\2\2\u00f6\u00f7\7h\2\2\u00f7"+
"\b\3\2\2\2\u00f8\u00f9\7.\2\2\u00f9\n\3\2\2\2\u00fa\u00fb\7?\2\2\u00fb"+
"\f\3\2\2\2\u00fc\u00fd\7*\2\2\u00fd\16\3\2\2\2\u00fe\u00ff\7+\2\2\u00ff"+
"\20\3\2\2\2\u0100\u0101\7}\2\2\u0101\22\3\2\2\2\u0102\u0103\7\177\2\2"+
"\u0103\24\3\2\2\2\u0104\u0105\7%\2\2\u0105\u0106\7r\2\2\u0106\u0107\7"+
"t\2\2\u0107\u0108\7c\2\2\u0108\u0109\7i\2\2\u0109\u010a\7o\2\2\u010a\u010b"+
"\7c\2\2\u010b\26\3\2\2\2\u010c\u010d\7t\2\2\u010d\u010e\7g\2\2\u010e\u010f"+
"\7u\2\2\u010f\u0110\7g\2\2\u0110\u0111\7t\2\2\u0111\u0112\7x\2\2\u0112"+
"\u0113\7g\2\2\u0113\30\3\2\2\2\u0114\u0115\7%\2\2\u0115\u0116\7t\2\2\u0116"+
"\u0117\7g\2\2\u0117\u0118\7u\2\2\u0118\u0119\7g\2\2\u0119\u011a\7t\2\2"+
"\u011a\u011b\7x\2\2\u011b\u011c\7g\2\2\u011c\32\3\2\2\2\u011d\u011e\7"+
"r\2\2\u011e\u011f\7e\2\2\u011f\34\3\2\2\2\u0120\u0121\7%\2\2\u0121\u0122"+
"\7r\2\2\u0122\u0123\7e\2\2\u0123\36\3\2\2\2\u0124\u0125\7v\2\2\u0125\u0126"+
"\7c\2\2\u0126\u0127\7t\2\2\u0127\u0128\7i\2\2\u0128\u0129\7g\2\2\u0129"+
"\u012a\7v\2\2\u012a \3\2\2\2\u012b\u012c\7%\2\2\u012c\u012d\7v\2\2\u012d"+
"\u012e\7c\2\2\u012e\u012f\7t\2\2\u012f\u0130\7i\2\2\u0130\u0131\7g\2\2"+
"\u0131\u0132\7v\2\2\u0132\"\3\2\2\2\u0133\u0134\7n\2\2\u0134\u0135\7k"+
"\2\2\u0135\u0136\7p\2\2\u0136\u0137\7m\2\2\u0137$\3\2\2\2\u0138\u0139"+
"\7%\2\2\u0139\u013a\7n\2\2\u013a\u013b\7k\2\2\u013b\u013c\7p\2\2\u013c"+
"\u013d\7m\2\2\u013d&\3\2\2\2\u013e\u013f\7g\2\2\u013f\u0140\7p\2\2\u0140"+
"\u0141\7e\2\2\u0141\u0142\7q\2\2\u0142\u0143\7f\2\2\u0143\u0144\7k\2\2"+
"\u0144\u0145\7p\2\2\u0145\u0146\7i\2\2\u0146(\3\2\2\2\u0147\u0148\7%\2"+
"\2\u0148\u0149\7g\2\2\u0149\u014a\7p\2\2\u014a\u014b\7e\2\2\u014b\u014c"+
"\7q\2\2\u014c\u014d\7f\2\2\u014d\u014e\7k\2\2\u014e\u014f\7p\2\2\u014f"+
"\u0150\7i\2\2\u0150*\3\2\2\2\u0151\u0152\7e\2\2\u0152\u0153\7q\2\2\u0153"+
"\u0154\7p\2\2\u0154\u0155\7u\2\2\u0155\u0156\7v\2\2\u0156,\3\2\2\2\u0157"+
"\u0158\7g\2\2\u0158\u0159\7z\2\2\u0159\u015a\7v\2\2\u015a\u015b\7g\2\2"+
"\u015b\u015c\7t\2\2\u015c\u015d\7p\2\2\u015d.\3\2\2\2\u015e\u015f\7c\2"+
"\2\u015f\u0160\7n\2\2\u0160\u0161\7k\2\2\u0161\u0162\7i\2\2\u0162\u0163"+
"\7p\2\2\u0163\60\3\2\2\2\u0164\u0165\7t\2\2\u0165\u0166\7g\2\2\u0166\u0167"+
"\7i\2\2\u0167\u0168\7k\2\2\u0168\u0169\7u\2\2\u0169\u016a\7v\2\2\u016a"+
"\u016b\7g\2\2\u016b\u016c\7t\2\2\u016c\62\3\2\2\2\u016d\u016e\7k\2\2\u016e"+
"\u016f\7p\2\2\u016f\u0170\7n\2\2\u0170\u0171\7k\2\2\u0171\u0172\7p\2\2"+
"\u0172\u0173\7g\2\2\u0173\64\3\2\2\2\u0174\u0175\7x\2\2\u0175\u0176\7"+
"q\2\2\u0176\u0177\7n\2\2\u0177\u0178\7c\2\2\u0178\u0179\7v\2\2\u0179\u017a"+
"\7k\2\2\u017a\u017b\7n\2\2\u017b\u017c\7g\2\2\u017c\66\3\2\2\2\u017d\u017e"+
"\7k\2\2\u017e\u017f\7p\2\2\u017f\u0180\7v\2\2\u0180\u0181\7g\2\2\u0181"+
"\u0182\7t\2\2\u0182\u0183\7t\2\2\u0183\u0184\7w\2\2\u0184\u0185\7r\2\2"+
"\u0185\u0186\7v\2\2\u01868\3\2\2\2\u0187\u0188\7k\2\2\u0188\u0189\7h\2"+
"\2\u0189:\3\2\2\2\u018a\u018b\7g\2\2\u018b\u018c\7n\2\2\u018c\u018d\7"+
"u\2\2\u018d\u018e\7g\2\2\u018e<\3\2\2\2\u018f\u0190\7y\2\2\u0190\u0191"+
"\7j\2\2\u0191\u0192\7k\2\2\u0192\u0193\7n\2\2\u0193\u0194\7g\2\2\u0194"+
">\3\2\2\2\u0195\u0196\7f\2\2\u0196\u0197\7q\2\2\u0197@\3\2\2\2\u0198\u0199"+
"\7h\2\2\u0199\u019a\7q\2\2\u019a\u019b\7t\2\2\u019bB\3\2\2\2\u019c\u019d"+
"\7t\2\2\u019d\u019e\7g\2\2\u019e\u019f\7v\2\2\u019f\u01a0\7w\2\2\u01a0"+
"\u01a1\7t\2\2\u01a1\u01a2\7p\2\2\u01a2D\3\2\2\2\u01a3\u01a4\7d\2\2\u01a4"+
"\u01a5\7t\2\2\u01a5\u01a6\7g\2\2\u01a6\u01a7\7c\2\2\u01a7\u01a8\7m\2\2"+
"\u01a8F\3\2\2\2\u01a9\u01aa\7e\2\2\u01aa\u01ab\7q\2\2\u01ab\u01ac\7p\2"+
"\2\u01ac\u01ad\7v\2\2\u01ad\u01ae\7k\2\2\u01ae\u01af\7p\2\2\u01af\u01b0"+
"\7w\2\2\u01b0\u01b1\7g\2\2\u01b1H\3\2\2\2\u01b2\u01b3\7c\2\2\u01b3\u01b4"+
"\7u\2\2\u01b4\u01b5\7o\2\2\u01b5J\3\2\2\2\u01b6\u01b7\7<\2\2\u01b7L\3"+
"\2\2\2\u01b8\u01b9\7\60\2\2\u01b9\u01ba\7\60\2\2\u01baN\3\2\2\2\u01bb"+
"\u01bc\7u\2\2\u01bc\u01bd\7k\2\2\u01bd\u01be\7i\2\2\u01be\u01bf\7p\2\2"+
"\u01bf\u01c0\7g\2\2\u01c0\u01c1\7f\2\2\u01c1P\3\2\2\2\u01c2\u01c3\7w\2"+
"\2\u01c3\u01c4\7p\2\2\u01c4\u01c5\7u\2\2\u01c5\u01c6\7k\2\2\u01c6\u01c7"+
"\7i\2\2\u01c7\u01c8\7p\2\2\u01c8\u01c9\7g\2\2\u01c9\u01ca\7f\2\2\u01ca"+
"R\3\2\2\2\u01cb\u01cc\7,\2\2\u01ccT\3\2\2\2\u01cd\u01ce\7]\2\2\u01ceV"+
"\3\2\2\2\u01cf\u01d0\7_\2\2\u01d0X\3\2\2\2\u01d1\u01d2\7u\2\2\u01d2\u01d3"+
"\7v\2\2\u01d3\u01d4\7t\2\2\u01d4\u01d5\7w\2\2\u01d5\u01d6\7e\2\2\u01d6"+
"\u01d7\7v\2\2\u01d7Z\3\2\2\2\u01d8\u01d9\7g\2\2\u01d9\u01da\7p\2\2\u01da"+
"\u01db\7w\2\2\u01db\u01dc\7o\2\2\u01dc\\\3\2\2\2\u01dd\u01de\7\60\2\2"+
"\u01de^\3\2\2\2\u01df\u01e0\7/\2\2\u01e0\u01e1\7@\2\2\u01e1`\3\2\2\2\u01e2"+
"\u01e3\7u\2\2\u01e3\u01e4\7k\2\2\u01e4\u01e5\7|\2\2\u01e5\u01e6\7g\2\2"+
"\u01e6\u01e7\7q\2\2\u01e7\u01e8\7h\2\2\u01e8b\3\2\2\2\u01e9\u01ea\7v\2"+
"\2\u01ea\u01eb\7{\2\2\u01eb\u01ec\7r\2\2\u01ec\u01ed\7g\2\2\u01ed\u01ee"+
"\7k\2\2\u01ee\u01ef\7f\2\2\u01efd\3\2\2\2\u01f0\u01f1\7/\2\2\u01f1\u01f2"+
"\7/\2\2\u01f2f\3\2\2\2\u01f3\u01f4\7-\2\2\u01f4\u01f5\7-\2\2\u01f5h\3"+
"\2\2\2\u01f6\u01f7\7-\2\2\u01f7j\3\2\2\2\u01f8\u01f9\7/\2\2\u01f9l\3\2"+
"\2\2\u01fa\u01fb\7#\2\2\u01fbn\3\2\2\2\u01fc\u01fd\7(\2\2\u01fdp\3\2\2"+
"\2\u01fe\u01ff\7\u0080\2\2\u01ffr\3\2\2\2\u0200\u0201\7@\2\2\u0201\u0202"+
"\7@\2\2\u0202t\3\2\2\2\u0203\u0204\7>\2\2\u0204\u0205\7>\2\2\u0205v\3"+
"\2\2\2\u0206\u0207\7\61\2\2\u0207x\3\2\2\2\u0208\u0209\7\'\2\2\u0209z"+
"\3\2\2\2\u020a\u020b\7>\2\2\u020b|\3\2\2\2\u020c\u020d\7@\2\2\u020d~\3"+
"\2\2\2\u020e\u020f\7?\2\2\u020f\u0210\7?\2\2\u0210\u0080\3\2\2\2\u0211"+
"\u0212\7#\2\2\u0212\u0213\7?\2\2\u0213\u0082\3\2\2\2\u0214\u0215\7>\2"+
"\2\u0215\u0216\7?\2\2\u0216\u0084\3\2\2\2\u0217\u0218\7@\2\2\u0218\u0219"+
"\7?\2\2\u0219\u0086\3\2\2\2\u021a\u021b\7`\2\2\u021b\u0088\3\2\2\2\u021c"+
"\u021d\7~\2\2\u021d\u008a\3\2\2\2\u021e\u021f\7(\2\2\u021f\u0220\7(\2"+
"\2\u0220\u008c\3\2\2\2\u0221\u0222\7~\2\2\u0222\u0223\7~\2\2\u0223\u008e"+
"\3\2\2\2\u0224\u0225\7A\2\2\u0225\u0090\3\2\2\2\u0226\u0227\7-\2\2\u0227"+
"\u0228\7?\2\2\u0228\u0092\3\2\2\2\u0229\u022a\7/\2\2\u022a\u022b\7?\2"+
"\2\u022b\u0094\3\2\2\2\u022c\u022d\7,\2\2\u022d\u022e\7?\2\2\u022e\u0096"+
"\3\2\2\2\u022f\u0230\7\61\2\2\u0230\u0231\7?\2\2\u0231\u0098\3\2\2\2\u0232"+
"\u0233\7\'\2\2\u0233\u0234\7?\2\2\u0234\u009a\3\2\2\2\u0235\u0236\7>\2"+
"\2\u0236\u0237\7>\2\2\u0237\u0238\7?\2\2\u0238\u009c\3\2\2\2\u0239\u023a"+
"\7@\2\2\u023a\u023b\7@\2\2\u023b\u023c\7?\2\2\u023c\u009e\3\2\2\2\u023d"+
"\u023e\7(\2\2\u023e\u023f\7?\2\2\u023f\u00a0\3\2\2\2\u0240\u0241\7~\2"+
"\2\u0241\u0242\7?\2\2\u0242\u00a2\3\2\2\2\u0243\u0244\7`\2\2\u0244\u0245"+
"\7?\2\2\u0245\u00a4\3\2\2\2\u0246\u0247\7m\2\2\u0247\u0248\7k\2\2\u0248"+
"\u0249\7e\2\2\u0249\u024a\7m\2\2\u024a\u024b\7c\2\2\u024b\u024c\7u\2\2"+
"\u024c\u024d\7o\2\2\u024d\u00a6\3\2\2\2\u024e\u024f\7t\2\2\u024f\u0250"+
"\7g\2\2\u0250\u0251\7u\2\2\u0251\u0252\7q\2\2\u0252\u0253\7w\2\2\u0253"+
"\u0254\7t\2\2\u0254\u0255\7e\2\2\u0255\u0256\7g\2\2\u0256\u00a8\3\2\2"+
"\2\u0257\u0258\7w\2\2\u0258\u0259\7u\2\2\u0259\u025a\7g\2\2\u025a\u025b"+
"\7u\2\2\u025b\u00aa\3\2\2\2\u025c\u025d\7e\2\2\u025d\u025e\7n\2\2\u025e"+
"\u025f\7q\2\2\u025f\u0260\7d\2\2\u0260\u0261\7d\2\2\u0261\u0262\7g\2\2"+
"\u0262\u0263\7t\2\2\u0263\u0264\7u\2\2\u0264\u00ac\3\2\2\2\u0265\u0266"+
"\7d\2\2\u0266\u0267\7{\2\2\u0267\u0268\7v\2\2\u0268\u0269\7g\2\2\u0269"+
"\u026a\7u\2\2\u026a\u00ae\3\2\2\2\u026b\u026c\7e\2\2\u026c\u026d\7{\2"+
"\2\u026d\u026e\7e\2\2\u026e\u026f\7n\2\2\u026f\u0270\7g\2\2\u0270\u0271"+
"\7u\2\2\u0271\u00b0\3\2\2\2\u0272\u0273\7\60\2\2\u0273\u0274\7d\2\2\u0274"+
"\u0275\7{\2\2\u0275\u0276\7v\2\2\u0276\u0277\7g\2\2\u0277\u00b2\3\2\2"+
"\2\u0278\u0279\7%\2\2\u0279\u00b4\3\2\2\2\u027a\u027b\7d\2\2\u027b\u027c"+
"\7t\2\2\u027c\u0359\7m\2\2\u027d\u027e\7q\2\2\u027e\u027f\7t\2\2\u027f"+
"\u0359\7c\2\2\u0280\u0281\7m\2\2\u0281\u0282\7k\2\2\u0282\u0359\7n\2\2"+
"\u0283\u0284\7u\2\2\u0284\u0285\7n\2\2\u0285\u0359\7q\2\2\u0286\u0287"+
"\7p\2\2\u0287\u0288\7q\2\2\u0288\u0359\7r\2\2\u0289\u028a\7c\2\2\u028a"+
"\u028b\7u\2\2\u028b\u0359\7n\2\2\u028c\u028d\7r\2\2\u028d\u028e\7j\2\2"+
"\u028e\u0359\7r\2\2\u028f\u0290\7c\2\2\u0290\u0291\7p\2\2\u0291\u0359"+
"\7e\2\2\u0292\u0293\7d\2\2\u0293\u0294\7r\2\2\u0294\u0359\7n\2\2\u0295"+
"\u0296\7e\2\2\u0296\u0297\7n\2\2\u0297\u0359\7e\2\2\u0298\u0299\7l\2\2"+
"\u0299\u029a\7u\2\2\u029a\u0359\7t\2\2\u029b\u029c\7c\2\2\u029c\u029d"+
"\7p\2\2\u029d\u0359\7f\2\2\u029e\u029f\7t\2\2\u029f\u02a0\7n\2\2\u02a0"+
"\u0359\7c\2\2\u02a1\u02a2\7d\2\2\u02a2\u02a3\7k\2\2\u02a3\u0359\7v\2\2"+
"\u02a4\u02a5\7t\2\2\u02a5\u02a6\7q\2\2\u02a6\u0359\7n\2\2\u02a7\u02a8"+
"\7r\2\2\u02a8\u02a9\7n\2\2\u02a9\u0359\7c\2\2\u02aa\u02ab\7r\2\2\u02ab"+
"\u02ac\7n\2\2\u02ac\u0359\7r\2\2\u02ad\u02ae\7d\2\2\u02ae\u02af\7o\2\2"+
"\u02af\u0359\7k\2\2\u02b0\u02b1\7u\2\2\u02b1\u02b2\7g\2\2\u02b2\u0359"+
"\7e\2\2\u02b3\u02b4\7t\2\2\u02b4\u02b5\7v\2\2\u02b5\u0359\7k\2\2\u02b6"+
"\u02b7\7g\2\2\u02b7\u02b8\7q\2\2\u02b8\u0359\7t\2\2\u02b9\u02ba\7u\2\2"+
"\u02ba\u02bb\7t\2\2\u02bb\u0359\7g\2\2\u02bc\u02bd\7n\2\2\u02bd\u02be"+
"\7u\2\2\u02be\u0359\7t\2\2\u02bf\u02c0\7r\2\2\u02c0\u02c1\7j\2\2\u02c1"+
"\u0359\7c\2\2\u02c2\u02c3\7c\2\2\u02c3\u02c4\7n\2\2\u02c4\u0359\7t\2\2"+
"\u02c5\u02c6\7l\2\2\u02c6\u02c7\7o\2\2\u02c7\u0359\7r\2\2\u02c8\u02c9"+
"\7d\2\2\u02c9\u02ca\7x\2\2\u02ca\u0359\7e\2\2\u02cb\u02cc\7e\2\2\u02cc"+
"\u02cd\7n\2\2\u02cd\u0359\7k\2\2\u02ce\u02cf\7t\2\2\u02cf\u02d0\7v\2\2"+
"\u02d0\u0359\7u\2\2\u02d1\u02d2\7c\2\2\u02d2\u02d3\7f\2\2\u02d3\u0359"+
"\7e\2\2\u02d4\u02d5\7t\2\2\u02d5\u02d6\7t\2\2\u02d6\u0359\7c\2\2\u02d7"+
"\u02d8\7d\2\2\u02d8\u02d9\7x\2\2\u02d9\u0359\7u\2\2\u02da\u02db\7u\2\2"+
"\u02db\u02dc\7g\2\2\u02dc\u0359\7k\2\2\u02dd\u02de\7u\2\2\u02de\u02df"+
"\7c\2\2\u02df\u0359\7z\2\2\u02e0\u02e1\7u\2\2\u02e1\u02e2\7v\2\2\u02e2"+
"\u0359\7{\2\2\u02e3\u02e4\7u\2\2\u02e4\u02e5\7v\2\2\u02e5\u0359\7c\2\2"+
"\u02e6\u02e7\7u\2\2\u02e7\u02e8\7v\2\2\u02e8\u0359\7z\2\2\u02e9\u02ea"+
"\7f\2\2\u02ea\u02eb\7g\2\2\u02eb\u0359\7{\2\2\u02ec\u02ed\7v\2\2\u02ed"+
"\u02ee\7z\2\2\u02ee\u0359\7c\2\2\u02ef\u02f0\7z\2\2\u02f0\u02f1\7c\2\2"+
"\u02f1\u0359\7c\2\2\u02f2\u02f3\7d\2\2\u02f3\u02f4\7e\2\2\u02f4\u0359"+
"\7e\2\2\u02f5\u02f6\7c\2\2\u02f6\u02f7\7j\2\2\u02f7\u0359\7z\2\2\u02f8"+
"\u02f9\7v\2\2\u02f9\u02fa\7{\2\2\u02fa\u0359\7c\2\2\u02fb\u02fc\7v\2\2"+
"\u02fc\u02fd\7z\2\2\u02fd\u0359\7u\2\2\u02fe\u02ff\7v\2\2\u02ff\u0300"+
"\7c\2\2\u0300\u0359\7u\2\2\u0301\u0302\7u\2\2\u0302\u0303\7j\2\2\u0303"+
"\u0359\7{\2\2\u0304\u0305\7u\2\2\u0305\u0306\7j\2\2\u0306\u0359\7z\2\2"+
"\u0307\u0308\7n\2\2\u0308\u0309\7f\2\2\u0309\u0359\7{\2\2\u030a\u030b"+
"\7n\2\2\u030b\u030c\7f\2\2\u030c\u0359\7c\2\2\u030d\u030e\7n\2\2\u030e"+
"\u030f\7f\2\2\u030f\u0359\7z\2\2\u0310\u0311\7n\2\2\u0311\u0312\7c\2\2"+
"\u0312\u0359\7z\2\2\u0313\u0314\7v\2\2\u0314\u0315\7c\2\2\u0315\u0359"+
"\7{\2\2\u0316\u0317\7v\2\2\u0317\u0318\7c\2\2\u0318\u0359\7z\2\2\u0319"+
"\u031a\7d\2\2\u031a\u031b\7e\2\2\u031b\u0359\7u\2\2\u031c\u031d\7e\2\2"+
"\u031d\u031e\7n\2\2\u031e\u0359\7x\2\2\u031f\u0320\7v\2\2\u0320\u0321"+
"\7u\2\2\u0321\u0359\7z\2\2\u0322\u0323\7n\2\2\u0323\u0324\7c\2\2\u0324"+
"\u0359\7u\2\2\u0325\u0326\7e\2\2\u0326\u0327\7r\2\2\u0327\u0359\7{\2\2"+
"\u0328\u0329\7e\2\2\u0329\u032a\7o\2\2\u032a\u0359\7r\2\2\u032b\u032c"+
"\7e\2\2\u032c\u032d\7r\2\2\u032d\u0359\7z\2\2\u032e\u032f\7f\2\2\u032f"+
"\u0330\7e\2\2\u0330\u0359\7r\2\2\u0331\u0332\7f\2\2\u0332\u0333\7g\2\2"+
"\u0333\u0359\7e\2\2\u0334\u0335\7k\2\2\u0335\u0336\7p\2\2\u0336\u0359"+
"\7e\2\2\u0337\u0338\7c\2\2\u0338\u0339\7z\2\2\u0339\u0359\7u\2\2\u033a"+
"\u033b\7d\2\2\u033b\u033c\7p\2\2\u033c\u0359\7g\2\2\u033d\u033e\7e\2\2"+
"\u033e\u033f\7n\2\2\u033f\u0359\7f\2\2\u0340\u0341\7u\2\2\u0341\u0342"+
"\7d\2\2\u0342\u0359\7e\2\2\u0343\u0344\7k\2\2\u0344\u0345\7u\2\2\u0345"+
"\u0359\7e\2\2\u0346\u0347\7k\2\2\u0347\u0348\7p\2\2\u0348\u0359\7z\2\2"+
"\u0349\u034a\7d\2\2\u034a\u034b\7g\2\2\u034b\u0359\7s\2\2\u034c\u034d"+
"\7u\2\2\u034d\u034e\7g\2\2\u034e\u0359\7f\2\2\u034f\u0350\7f\2\2\u0350"+
"\u0351\7g\2\2\u0351\u0359\7z\2\2\u0352\u0353\7k\2\2\u0353\u0354\7p\2\2"+
"\u0354\u0359\7{\2\2\u0355\u0356\7t\2\2\u0356\u0357\7q\2\2\u0357\u0359"+
"\7t\2\2\u0358\u027a\3\2\2\2\u0358\u027d\3\2\2\2\u0358\u0280\3\2\2\2\u0358"+
"\u0283\3\2\2\2\u0358\u0286\3\2\2\2\u0358\u0289\3\2\2\2\u0358\u028c\3\2"+
"\2\2\u0358\u028f\3\2\2\2\u0358\u0292\3\2\2\2\u0358\u0295\3\2\2\2\u0358"+
"\u0298\3\2\2\2\u0358\u029b\3\2\2\2\u0358\u029e\3\2\2\2\u0358\u02a1\3\2"+
"\2\2\u0358\u02a4\3\2\2\2\u0358\u02a7\3\2\2\2\u0358\u02aa\3\2\2\2\u0358"+
"\u02ad\3\2\2\2\u0358\u02b0\3\2\2\2\u0358\u02b3\3\2\2\2\u0358\u02b6\3\2"+
"\2\2\u0358\u02b9\3\2\2\2\u0358\u02bc\3\2\2\2\u0358\u02bf\3\2\2\2\u0358"+
"\u02c2\3\2\2\2\u0358\u02c5\3\2\2\2\u0358\u02c8\3\2\2\2\u0358\u02cb\3\2"+
"\2\2\u0358\u02ce\3\2\2\2\u0358\u02d1\3\2\2\2\u0358\u02d4\3\2\2\2\u0358"+
"\u02d7\3\2\2\2\u0358\u02da\3\2\2\2\u0358\u02dd\3\2\2\2\u0358\u02e0\3\2"+
"\2\2\u0358\u02e3\3\2\2\2\u0358\u02e6\3\2\2\2\u0358\u02e9\3\2\2\2\u0358"+
"\u02ec\3\2\2\2\u0358\u02ef\3\2\2\2\u0358\u02f2\3\2\2\2\u0358\u02f5\3\2"+
"\2\2\u0358\u02f8\3\2\2\2\u0358\u02fb\3\2\2\2\u0358\u02fe\3\2\2\2\u0358"+
"\u0301\3\2\2\2\u0358\u0304\3\2\2\2\u0358\u0307\3\2\2\2\u0358\u030a\3\2"+
"\2\2\u0358\u030d\3\2\2\2\u0358\u0310\3\2\2\2\u0358\u0313\3\2\2\2\u0358"+
"\u0316\3\2\2\2\u0358\u0319\3\2\2\2\u0358\u031c\3\2\2\2\u0358\u031f\3\2"+
"\2\2\u0358\u0322\3\2\2\2\u0358\u0325\3\2\2\2\u0358\u0328\3\2\2\2\u0358"+
"\u032b\3\2\2\2\u0358\u032e\3\2\2\2\u0358\u0331\3\2\2\2\u0358\u0334\3\2"+
"\2\2\u0358\u0337\3\2\2\2\u0358\u033a\3\2\2\2\u0358\u033d\3\2\2\2\u0358"+
"\u0340\3\2\2\2\u0358\u0343\3\2\2\2\u0358\u0346\3\2\2\2\u0358\u0349\3\2"+
"\2\2\u0358\u034c\3\2\2\2\u0358\u034f\3\2\2\2\u0358\u0352\3\2\2\2\u0358"+
"\u0355\3\2\2\2\u0359\u00b6\3\2\2\2\u035a\u035b\7}\2\2\u035b\u035c\7}\2"+
"\2\u035c\u0360\3\2\2\2\u035d\u035f\13\2\2\2\u035e\u035d\3\2\2\2\u035f"+
"\u0362\3\2\2\2\u0360\u0361\3\2\2\2\u0360\u035e\3\2\2\2\u0361\u0363\3\2"+
"\2\2\u0362\u0360\3\2\2\2\u0363\u0364\7\177\2\2\u0364\u0365\7\177\2\2\u0365"+
"\u00b8\3\2\2\2\u0366\u0367\7d\2\2\u0367\u0368\7{\2\2\u0368\u0369\7v\2"+
"\2\u0369\u038c\7g\2\2\u036a\u036b\7y\2\2\u036b\u036c\7q\2\2\u036c\u036d"+
"\7t\2\2\u036d\u038c\7f\2\2\u036e\u036f\7f\2\2\u036f\u0370\7y\2\2\u0370"+
"\u0371\7q\2\2\u0371\u0372\7t\2\2\u0372\u038c\7f\2\2\u0373\u0374\7d\2\2"+
"\u0374\u0375\7q\2\2\u0375\u0376\7q\2\2\u0376\u038c\7n\2\2\u0377\u0378"+
"\7e\2\2\u0378\u0379\7j\2\2\u0379\u037a\7c\2\2\u037a\u038c\7t\2\2\u037b"+
"\u037c\7u\2\2\u037c\u037d\7j\2\2\u037d\u037e\7q\2\2\u037e\u037f\7t\2\2"+
"\u037f\u038c\7v\2\2\u0380\u0381\7k\2\2\u0381\u0382\7p\2\2\u0382\u038c"+
"\7v\2\2\u0383\u0384\7n\2\2\u0384\u0385\7q\2\2\u0385\u0386\7p\2\2\u0386"+
"\u038c\7i\2\2\u0387\u0388\7x\2\2\u0388\u0389\7q\2\2\u0389\u038a\7k\2\2"+
"\u038a\u038c\7f\2\2\u038b\u0366\3\2\2\2\u038b\u036a\3\2\2\2\u038b\u036e"+
"\3\2\2\2\u038b\u0373\3\2\2\2\u038b\u0377\3\2\2\2\u038b\u037b\3\2\2\2\u038b"+
"\u0380\3\2\2\2\u038b\u0383\3\2\2\2\u038b\u0387\3\2\2\2\u038c\u00ba\3\2"+
"\2\2\u038d\u0393\7$\2\2\u038e\u038f\7^\2\2\u038f\u0392\7$\2\2\u0390\u0392"+
"\n\2\2\2\u0391\u038e\3\2\2\2\u0391\u0390\3\2\2\2\u0392\u0395\3\2\2\2\u0393"+
"\u0391\3\2\2\2\u0393\u0394\3\2\2\2\u0394\u0396\3\2\2\2\u0395\u0393\3\2"+
"\2\2\u0396\u0398\7$\2\2\u0397\u0399\t\3\2\2\u0398\u0397\3\2\2\2\u0398"+
"\u0399\3\2\2\2\u0399\u039e\3\2\2\2\u039a\u039c\t\4\2\2\u039b\u039d\t\5"+
"\2\2\u039c\u039b\3\2\2\2\u039c\u039d\3\2\2\2\u039d\u039f\3\2\2\2\u039e"+
"\u039a\3\2\2\2\u039e\u039f\3\2\2\2\u039f\u03a1\3\2\2\2\u03a0\u03a2\t\3"+
"\2\2\u03a1\u03a0\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u00bc\3\2\2\2\u03a3"+
"\u03a7\7)\2\2\u03a4\u03a5\7^\2\2\u03a5\u03a8\7)\2\2\u03a6\u03a8\n\6\2"+
"\2\u03a7\u03a4\3\2\2\2\u03a7\u03a6\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9\u03aa"+
"\7)\2\2\u03aa\u00be\3\2\2\2\u03ab\u03ac\7v\2\2\u03ac\u03ad\7t\2\2\u03ad"+
"\u03ae\7w\2\2\u03ae\u03b5\7g\2\2\u03af\u03b0\7h\2\2\u03b0\u03b1\7c\2\2"+
"\u03b1\u03b2\7n\2\2\u03b2\u03b3\7u\2\2\u03b3\u03b5\7g\2\2\u03b4\u03ab"+
"\3\2\2\2\u03b4\u03af\3\2\2\2\u03b5\u00c0\3\2\2\2\u03b6\u03b9\5\u00c3b"+
"\2\u03b7\u03b9\5\u00cbf\2\u03b8\u03b6\3\2\2\2\u03b8\u03b7\3\2\2\2\u03b9"+
"\u00c2\3\2\2\2\u03ba\u03be\5\u00c5c\2\u03bb\u03be\5\u00c7d\2\u03bc\u03be"+
"\5\u00c9e\2\u03bd\u03ba\3\2\2\2\u03bd\u03bb\3\2\2\2\u03bd\u03bc\3\2\2"+
"\2\u03be\u00c4\3\2\2\2\u03bf\u03c5\7\'\2\2\u03c0\u03c1\7\62\2\2\u03c1"+
"\u03c5\7d\2\2\u03c2\u03c3\7\62\2\2\u03c3\u03c5\7D\2\2\u03c4\u03bf\3\2"+
"\2\2\u03c4\u03c0\3\2\2\2\u03c4\u03c2\3\2\2\2\u03c5\u03c9\3\2\2\2\u03c6"+
"\u03c8\5\u00d3j\2\u03c7\u03c6\3\2\2\2\u03c8\u03cb\3\2\2\2\u03c9\u03c7"+
"\3\2\2\2\u03c9\u03ca\3\2\2\2\u03ca\u03cc\3\2\2\2\u03cb\u03c9\3\2\2\2\u03cc"+
"\u03ce\7\60\2\2\u03cd\u03cf\5\u00d3j\2\u03ce\u03cd\3\2\2\2\u03cf\u03d0"+
"\3\2\2\2\u03d0\u03ce\3\2\2\2\u03d0\u03d1\3\2\2\2\u03d1\u00c6\3\2\2\2\u03d2"+
"\u03d4\5\u00d5k\2\u03d3\u03d2\3\2\2\2\u03d4\u03d7\3\2\2\2\u03d5\u03d3"+
"\3\2\2\2\u03d5\u03d6\3\2\2\2\u03d6\u03d8\3\2\2\2\u03d7\u03d5\3\2\2\2\u03d8"+
"\u03da\7\60\2\2\u03d9\u03db\5\u00d5k\2\u03da\u03d9\3\2\2\2\u03db\u03dc"+
"\3\2\2\2\u03dc\u03da\3\2\2\2\u03dc\u03dd\3\2\2\2\u03dd\u00c8\3\2\2\2\u03de"+
"\u03e4\7&\2\2\u03df\u03e0\7\62\2\2\u03e0\u03e4\7z\2\2\u03e1\u03e2\7\62"+
"\2\2\u03e2\u03e4\7Z\2\2\u03e3\u03de\3\2\2\2\u03e3\u03df\3\2\2\2\u03e3"+
"\u03e1\3\2\2\2\u03e4\u03e8\3\2\2\2\u03e5\u03e7\5\u00d7l\2\u03e6\u03e5"+
"\3\2\2\2\u03e7\u03ea\3\2\2\2\u03e8\u03e6\3\2\2\2\u03e8\u03e9\3\2\2\2\u03e9"+
"\u03eb\3\2\2\2\u03ea\u03e8\3\2\2\2\u03eb\u03ed\7\60\2\2\u03ec\u03ee\5"+
"\u00d7l\2\u03ed\u03ec\3\2\2\2\u03ee\u03ef\3\2\2\2\u03ef\u03ed\3\2\2\2"+
"\u03ef\u03f0\3\2\2\2\u03f0\u00ca\3\2\2\2\u03f1\u03f5\5\u00cfh\2\u03f2"+
"\u03f5\5\u00d1i\2\u03f3\u03f5\5\u00cdg\2\u03f4\u03f1\3\2\2\2\u03f4\u03f2"+
"\3\2\2\2\u03f4\u03f3\3\2\2\2\u03f5\u03f9\3\2\2\2\u03f6\u03f7\t\7\2\2\u03f7"+
"\u03fa\t\b\2\2\u03f8\u03fa\7n\2\2\u03f9\u03f6\3\2\2\2\u03f9\u03f8\3\2"+
"\2\2\u03f9\u03fa\3\2\2\2\u03fa\u00cc\3\2\2\2\u03fb\u03fc\7\62\2\2\u03fc"+
"\u03fe\t\t\2\2\u03fd\u03ff\5\u00d3j\2\u03fe\u03fd\3\2\2\2\u03ff\u0400"+
"\3\2\2\2\u0400\u03fe\3\2\2\2\u0400\u0401\3\2\2\2\u0401\u0409\3\2\2\2\u0402"+
"\u0404\7\'\2\2\u0403\u0405\5\u00d3j\2\u0404\u0403\3\2\2\2\u0405\u0406"+
"\3\2\2\2\u0406\u0404\3\2\2\2\u0406\u0407\3\2\2\2\u0407\u0409\3\2\2\2\u0408"+
"\u03fb\3\2\2\2\u0408\u0402\3\2\2\2\u0409\u00ce\3\2\2\2\u040a\u040c\5\u00d5"+
"k\2\u040b\u040a\3\2\2\2\u040c\u040d\3\2\2\2\u040d\u040b\3\2\2\2\u040d"+
"\u040e\3\2\2\2\u040e\u00d0\3\2\2\2\u040f\u0415\7&\2\2\u0410\u0411\7\62"+
"\2\2\u0411\u0415\7z\2\2\u0412\u0413\7\62\2\2\u0413\u0415\7Z\2\2\u0414"+
"\u040f\3\2\2\2\u0414\u0410\3\2\2\2\u0414\u0412\3\2\2\2\u0415\u0417\3\2"+
"\2\2\u0416\u0418\5\u00d7l\2\u0417\u0416\3\2\2\2\u0418\u0419\3\2\2\2\u0419"+
"\u0417\3\2\2\2\u0419\u041a\3\2\2\2\u041a\u00d2\3\2\2\2\u041b\u041c\t\n"+
"\2\2\u041c\u00d4\3\2\2\2\u041d\u041e\t\13\2\2\u041e\u00d6\3\2\2\2\u041f"+
"\u0420\t\f\2\2\u0420\u00d8\3\2\2\2\u0421\u0425\5\u00dbn\2\u0422\u0424"+
"\5\u00ddo\2\u0423\u0422\3\2\2\2\u0424\u0427\3\2\2\2\u0425\u0423\3\2\2"+
"\2\u0425\u0426\3\2\2\2\u0426\u00da\3\2\2\2\u0427\u0425\3\2\2\2\u0428\u0429"+
"\t\r\2\2\u0429\u00dc\3\2\2\2\u042a\u042b\t\16\2\2\u042b\u00de\3\2\2\2"+
"\u042c\u0430\7#\2\2\u042d\u042f\5\u00ddo\2\u042e\u042d\3\2\2\2\u042f\u0432"+
"\3\2\2\2\u0430\u042e\3\2\2\2\u0430\u0431\3\2\2\2\u0431\u0434\3\2\2\2\u0432"+
"\u0430\3\2\2\2\u0433\u0435\t\17\2\2\u0434\u0433\3\2\2\2\u0435\u0436\3"+
"\2\2\2\u0436\u0434\3\2\2\2\u0436\u0437\3\2\2\2\u0437\u00e0\3\2\2\2\u0438"+
"\u043a\t\20\2\2\u0439\u0438\3\2\2\2\u043a\u043b\3\2\2\2\u043b\u0439\3"+
"\2\2\2\u043b\u043c\3\2\2\2\u043c\u043d\3\2\2\2\u043d\u043e\bq\2\2\u043e"+
"\u00e2\3\2\2\2\u043f\u0440\7\61\2\2\u0440\u0441\7\61\2\2\u0441\u0445\3"+
"\2\2\2\u0442\u0444\n\21\2\2\u0443\u0442\3\2\2\2\u0444\u0447\3\2\2\2\u0445"+
"\u0443\3\2\2\2\u0445\u0446\3\2\2\2\u0446\u0448\3\2\2\2\u0447\u0445\3\2"+
"\2\2\u0448\u0449\br\3\2\u0449\u00e4\3\2\2\2\u044a\u044b\7\61\2\2\u044b"+
"\u044c\7,\2\2\u044c\u0450\3\2\2\2\u044d\u044f\13\2\2\2\u044e\u044d\3\2"+
"\2\2\u044f\u0452\3\2\2\2\u0450\u0451\3\2\2\2\u0450\u044e\3\2\2\2\u0451"+
"\u0453\3\2\2\2\u0452\u0450\3\2\2\2\u0453\u0454\7,\2\2\u0454\u0455\7\61"+
"\2\2\u0455\u0456\3\2\2\2\u0456\u0457\bs\3\2\u0457\u00e6\3\2\2\2&\2\u0358"+
"\u0360\u038b\u0391\u0393\u0398\u039c\u039e\u03a1\u03a7\u03b4\u03b8\u03bd"+
"\u03c4\u03c9\u03d0\u03d5\u03dc\u03e3\u03e8\u03ef\u03f4\u03f9\u0400\u0406"+
"\u0408\u040d\u0414\u0419\u0425\u0430\u0436\u043b\u0445\u0450\4\2\3\2\2"+
"\4\2";
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\3\2\3\2\3\2\3"+
"\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\6\3\6"+
"\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3"+
"\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+
"\r\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3"+
"\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3"+
"\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3"+
"\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3"+
"\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3"+
"\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3"+
"\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3"+
"\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3"+
"\35\3\35\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3"+
"\37\3 \3 \3 \3 \3 \3 \3!\3!\3!\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3"+
"$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%\3%\3%\3%\3&\3&\3&\3&\3\'\3\'\3(\3("+
"\3(\3)\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3*\3*\3*\3+\3+\3,\3,\3-\3-"+
"\3.\3.\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3\60\3\60\3\61\3\61\3\61\3\62\3\62"+
"\3\62\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\64\3\64"+
"\3\64\3\65\3\65\3\65\3\66\3\66\3\67\3\67\38\38\39\39\3:\3:\3;\3;\3;\3"+
"<\3<\3<\3=\3=\3>\3>\3?\3?\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3C\3D\3D\3D\3"+
"E\3E\3F\3F\3G\3G\3G\3H\3H\3H\3I\3I\3J\3J\3J\3K\3K\3K\3L\3L\3L\3M\3M\3"+
"M\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3Q\3Q\3Q\3R\3R\3R\3S\3S\3S\3T\3T\3"+
"T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V\3V\3W\3W\3W\3"+
"W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3"+
"Z\3Z\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+
"\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\5\\\u0367\n"+
"\\\3]\3]\3]\3]\7]\u036d\n]\f]\16]\u0370\13]\3]\3]\3]\3^\3^\3^\3^\3^\3"+
"^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3"+
"^\3^\3^\3^\3^\3^\3^\3^\3^\5^\u039a\n^\3_\3_\3_\3_\7_\u03a0\n_\f_\16_\u03a3"+
"\13_\3_\3_\5_\u03a7\n_\3_\3_\5_\u03ab\n_\5_\u03ad\n_\3_\5_\u03b0\n_\3"+
"`\3`\3`\3`\5`\u03b6\n`\3`\3`\3a\3a\3a\3a\3a\3a\3a\3a\3a\5a\u03c3\na\3"+
"b\3b\5b\u03c7\nb\3c\3c\3c\5c\u03cc\nc\3d\3d\3d\3d\3d\5d\u03d3\nd\3d\7"+
"d\u03d6\nd\fd\16d\u03d9\13d\3d\3d\6d\u03dd\nd\rd\16d\u03de\3e\7e\u03e2"+
"\ne\fe\16e\u03e5\13e\3e\3e\6e\u03e9\ne\re\16e\u03ea\3f\3f\3f\3f\3f\5f"+
"\u03f2\nf\3f\7f\u03f5\nf\ff\16f\u03f8\13f\3f\3f\6f\u03fc\nf\rf\16f\u03fd"+
"\3g\3g\3g\5g\u0403\ng\3g\3g\3g\5g\u0408\ng\3h\3h\3h\6h\u040d\nh\rh\16"+
"h\u040e\3h\3h\6h\u0413\nh\rh\16h\u0414\5h\u0417\nh\3i\6i\u041a\ni\ri\16"+
"i\u041b\3j\3j\3j\3j\3j\5j\u0423\nj\3j\6j\u0426\nj\rj\16j\u0427\3k\3k\3"+
"l\3l\3m\3m\3n\3n\7n\u0432\nn\fn\16n\u0435\13n\3o\3o\3p\3p\3q\3q\7q\u043d"+
"\nq\fq\16q\u0440\13q\3q\6q\u0443\nq\rq\16q\u0444\3r\6r\u0448\nr\rr\16"+
"r\u0449\3r\3r\3s\3s\3s\3s\7s\u0452\ns\fs\16s\u0455\13s\3s\3s\3t\3t\3t"+
"\3t\7t\u045d\nt\ft\16t\u0460\13t\3t\3t\3t\3t\3t\4\u036e\u045e\2u\3\3\5"+
"\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21"+
"!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!"+
"A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s"+
";u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008f"+
"I\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3"+
"S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7"+
"]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cb"+
"g\u00cdh\u00cfi\u00d1j\u00d3k\u00d5\2\u00d7\2\u00d9\2\u00dbl\u00dd\2\u00df"+
"\2\u00e1m\u00e3n\u00e5o\u00e7p\3\2\22\3\2$$\3\2||\4\2rruu\4\2ooww\3\2"+
"))\4\2uuww\7\2dfkknnuuyy\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\"+
"aac|\6\2\62;C\\aac|\4\2--//\6\2\13\f\17\17\"\"\u00a2\u00a2\4\2\f\f\17"+
"\17\2\u04d8\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2"+
"\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27"+
"\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2"+
"\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2"+
"\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2"+
"\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2"+
"\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S"+
"\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2"+
"\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2"+
"\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y"+
"\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3"+
"\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2"+
"\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095"+
"\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2"+
"\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7"+
"\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2"+
"\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9"+
"\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2"+
"\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb"+
"\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2"+
"\2\2\u00db\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7"+
"\3\2\2\2\3\u00e9\3\2\2\2\5\u00f0\3\2\2\2\7\u00f2\3\2\2\2\t\u00fa\3\2\2"+
"\2\13\u00fc\3\2\2\2\r\u00fe\3\2\2\2\17\u0100\3\2\2\2\21\u0102\3\2\2\2"+
"\23\u0104\3\2\2\2\25\u0106\3\2\2\2\27\u010e\3\2\2\2\31\u0116\3\2\2\2\33"+
"\u011f\3\2\2\2\35\u0122\3\2\2\2\37\u0126\3\2\2\2!\u012d\3\2\2\2#\u0135"+
"\3\2\2\2%\u013a\3\2\2\2\'\u0143\3\2\2\2)\u014c\3\2\2\2+\u0155\3\2\2\2"+
"-\u015f\3\2\2\2/\u0165\3\2\2\2\61\u016c\3\2\2\2\63\u0172\3\2\2\2\65\u017b"+
"\3\2\2\2\67\u0182\3\2\2\29\u018b\3\2\2\2;\u0195\3\2\2\2=\u0198\3\2\2\2"+
"?\u019d\3\2\2\2A\u01a3\3\2\2\2C\u01a6\3\2\2\2E\u01aa\3\2\2\2G\u01b1\3"+
"\2\2\2I\u01b7\3\2\2\2K\u01c0\3\2\2\2M\u01c4\3\2\2\2O\u01c6\3\2\2\2Q\u01c9"+
"\3\2\2\2S\u01d0\3\2\2\2U\u01d9\3\2\2\2W\u01db\3\2\2\2Y\u01dd\3\2\2\2["+
"\u01df\3\2\2\2]\u01e6\3\2\2\2_\u01eb\3\2\2\2a\u01ed\3\2\2\2c\u01f0\3\2"+
"\2\2e\u01f7\3\2\2\2g\u01fe\3\2\2\2i\u0201\3\2\2\2k\u0204\3\2\2\2m\u0206"+
"\3\2\2\2o\u0208\3\2\2\2q\u020a\3\2\2\2s\u020c\3\2\2\2u\u020e\3\2\2\2w"+
"\u0211\3\2\2\2y\u0214\3\2\2\2{\u0216\3\2\2\2}\u0218\3\2\2\2\177\u021a"+
"\3\2\2\2\u0081\u021c\3\2\2\2\u0083\u021f\3\2\2\2\u0085\u0222\3\2\2\2\u0087"+
"\u0225\3\2\2\2\u0089\u0228\3\2\2\2\u008b\u022a\3\2\2\2\u008d\u022c\3\2"+
"\2\2\u008f\u022f\3\2\2\2\u0091\u0232\3\2\2\2\u0093\u0234\3\2\2\2\u0095"+
"\u0237\3\2\2\2\u0097\u023a\3\2\2\2\u0099\u023d\3\2\2\2\u009b\u0240\3\2"+
"\2\2\u009d\u0243\3\2\2\2\u009f\u0247\3\2\2\2\u00a1\u024b\3\2\2\2\u00a3"+
"\u024e\3\2\2\2\u00a5\u0251\3\2\2\2\u00a7\u0254\3\2\2\2\u00a9\u025c\3\2"+
"\2\2\u00ab\u0265\3\2\2\2\u00ad\u026a\3\2\2\2\u00af\u0273\3\2\2\2\u00b1"+
"\u0279\3\2\2\2\u00b3\u0280\3\2\2\2\u00b5\u0286\3\2\2\2\u00b7\u0366\3\2"+
"\2\2\u00b9\u0368\3\2\2\2\u00bb\u0399\3\2\2\2\u00bd\u039b\3\2\2\2\u00bf"+
"\u03b1\3\2\2\2\u00c1\u03c2\3\2\2\2\u00c3\u03c6\3\2\2\2\u00c5\u03cb\3\2"+
"\2\2\u00c7\u03d2\3\2\2\2\u00c9\u03e3\3\2\2\2\u00cb\u03f1\3\2\2\2\u00cd"+
"\u0402\3\2\2\2\u00cf\u0416\3\2\2\2\u00d1\u0419\3\2\2\2\u00d3\u0422\3\2"+
"\2\2\u00d5\u0429\3\2\2\2\u00d7\u042b\3\2\2\2\u00d9\u042d\3\2\2\2\u00db"+
"\u042f\3\2\2\2\u00dd\u0436\3\2\2\2\u00df\u0438\3\2\2\2\u00e1\u043a\3\2"+
"\2\2\u00e3\u0447\3\2\2\2\u00e5\u044d\3\2\2\2\u00e7\u0458\3\2\2\2\u00e9"+
"\u00ea\7k\2\2\u00ea\u00eb\7o\2\2\u00eb\u00ec\7r\2\2\u00ec\u00ed\7q\2\2"+
"\u00ed\u00ee\7t\2\2\u00ee\u00ef\7v\2\2\u00ef\4\3\2\2\2\u00f0\u00f1\7="+
"\2\2\u00f1\6\3\2\2\2\u00f2\u00f3\7v\2\2\u00f3\u00f4\7{\2\2\u00f4\u00f5"+
"\7r\2\2\u00f5\u00f6\7g\2\2\u00f6\u00f7\7f\2\2\u00f7\u00f8\7g\2\2\u00f8"+
"\u00f9\7h\2\2\u00f9\b\3\2\2\2\u00fa\u00fb\7.\2\2\u00fb\n\3\2\2\2\u00fc"+
"\u00fd\7?\2\2\u00fd\f\3\2\2\2\u00fe\u00ff\7*\2\2\u00ff\16\3\2\2\2\u0100"+
"\u0101\7+\2\2\u0101\20\3\2\2\2\u0102\u0103\7}\2\2\u0103\22\3\2\2\2\u0104"+
"\u0105\7\177\2\2\u0105\24\3\2\2\2\u0106\u0107\7%\2\2\u0107\u0108\7r\2"+
"\2\u0108\u0109\7t\2\2\u0109\u010a\7c\2\2\u010a\u010b\7i\2\2\u010b\u010c"+
"\7o\2\2\u010c\u010d\7c\2\2\u010d\26\3\2\2\2\u010e\u010f\7t\2\2\u010f\u0110"+
"\7g\2\2\u0110\u0111\7u\2\2\u0111\u0112\7g\2\2\u0112\u0113\7t\2\2\u0113"+
"\u0114\7x\2\2\u0114\u0115\7g\2\2\u0115\30\3\2\2\2\u0116\u0117\7%\2\2\u0117"+
"\u0118\7t\2\2\u0118\u0119\7g\2\2\u0119\u011a\7u\2\2\u011a\u011b\7g\2\2"+
"\u011b\u011c\7t\2\2\u011c\u011d\7x\2\2\u011d\u011e\7g\2\2\u011e\32\3\2"+
"\2\2\u011f\u0120\7r\2\2\u0120\u0121\7e\2\2\u0121\34\3\2\2\2\u0122\u0123"+
"\7%\2\2\u0123\u0124\7r\2\2\u0124\u0125\7e\2\2\u0125\36\3\2\2\2\u0126\u0127"+
"\7v\2\2\u0127\u0128\7c\2\2\u0128\u0129\7t\2\2\u0129\u012a\7i\2\2\u012a"+
"\u012b\7g\2\2\u012b\u012c\7v\2\2\u012c \3\2\2\2\u012d\u012e\7%\2\2\u012e"+
"\u012f\7v\2\2\u012f\u0130\7c\2\2\u0130\u0131\7t\2\2\u0131\u0132\7i\2\2"+
"\u0132\u0133\7g\2\2\u0133\u0134\7v\2\2\u0134\"\3\2\2\2\u0135\u0136\7n"+
"\2\2\u0136\u0137\7k\2\2\u0137\u0138\7p\2\2\u0138\u0139\7m\2\2\u0139$\3"+
"\2\2\2\u013a\u013b\7e\2\2\u013b\u013c\7q\2\2\u013c\u013d\7f\2\2\u013d"+
"\u013e\7g\2\2\u013e\u013f\7a\2\2\u013f\u0140\7u\2\2\u0140\u0141\7g\2\2"+
"\u0141\u0142\7i\2\2\u0142&\3\2\2\2\u0143\u0144\7f\2\2\u0144\u0145\7c\2"+
"\2\u0145\u0146\7v\2\2\u0146\u0147\7c\2\2\u0147\u0148\7a\2\2\u0148\u0149"+
"\7u\2\2\u0149\u014a\7g\2\2\u014a\u014b\7i\2\2\u014b(\3\2\2\2\u014c\u014d"+
"\7g\2\2\u014d\u014e\7p\2\2\u014e\u014f\7e\2\2\u014f\u0150\7q\2\2\u0150"+
"\u0151\7f\2\2\u0151\u0152\7k\2\2\u0152\u0153\7p\2\2\u0153\u0154\7i\2\2"+
"\u0154*\3\2\2\2\u0155\u0156\7%\2\2\u0156\u0157\7g\2\2\u0157\u0158\7p\2"+
"\2\u0158\u0159\7e\2\2\u0159\u015a\7q\2\2\u015a\u015b\7f\2\2\u015b\u015c"+
"\7k\2\2\u015c\u015d\7p\2\2\u015d\u015e\7i\2\2\u015e,\3\2\2\2\u015f\u0160"+
"\7e\2\2\u0160\u0161\7q\2\2\u0161\u0162\7p\2\2\u0162\u0163\7u\2\2\u0163"+
"\u0164\7v\2\2\u0164.\3\2\2\2\u0165\u0166\7g\2\2\u0166\u0167\7z\2\2\u0167"+
"\u0168\7v\2\2\u0168\u0169\7g\2\2\u0169\u016a\7t\2\2\u016a\u016b\7p\2\2"+
"\u016b\60\3\2\2\2\u016c\u016d\7c\2\2\u016d\u016e\7n\2\2\u016e\u016f\7"+
"k\2\2\u016f\u0170\7i\2\2\u0170\u0171\7p\2\2\u0171\62\3\2\2\2\u0172\u0173"+
"\7t\2\2\u0173\u0174\7g\2\2\u0174\u0175\7i\2\2\u0175\u0176\7k\2\2\u0176"+
"\u0177\7u\2\2\u0177\u0178\7v\2\2\u0178\u0179\7g\2\2\u0179\u017a\7t\2\2"+
"\u017a\64\3\2\2\2\u017b\u017c\7k\2\2\u017c\u017d\7p\2\2\u017d\u017e\7"+
"n\2\2\u017e\u017f\7k\2\2\u017f\u0180\7p\2\2\u0180\u0181\7g\2\2\u0181\66"+
"\3\2\2\2\u0182\u0183\7x\2\2\u0183\u0184\7q\2\2\u0184\u0185\7n\2\2\u0185"+
"\u0186\7c\2\2\u0186\u0187\7v\2\2\u0187\u0188\7k\2\2\u0188\u0189\7n\2\2"+
"\u0189\u018a\7g\2\2\u018a8\3\2\2\2\u018b\u018c\7k\2\2\u018c\u018d\7p\2"+
"\2\u018d\u018e\7v\2\2\u018e\u018f\7g\2\2\u018f\u0190\7t\2\2\u0190\u0191"+
"\7t\2\2\u0191\u0192\7w\2\2\u0192\u0193\7r\2\2\u0193\u0194\7v\2\2\u0194"+
":\3\2\2\2\u0195\u0196\7k\2\2\u0196\u0197\7h\2\2\u0197<\3\2\2\2\u0198\u0199"+
"\7g\2\2\u0199\u019a\7n\2\2\u019a\u019b\7u\2\2\u019b\u019c\7g\2\2\u019c"+
">\3\2\2\2\u019d\u019e\7y\2\2\u019e\u019f\7j\2\2\u019f\u01a0\7k\2\2\u01a0"+
"\u01a1\7n\2\2\u01a1\u01a2\7g\2\2\u01a2@\3\2\2\2\u01a3\u01a4\7f\2\2\u01a4"+
"\u01a5\7q\2\2\u01a5B\3\2\2\2\u01a6\u01a7\7h\2\2\u01a7\u01a8\7q\2\2\u01a8"+
"\u01a9\7t\2\2\u01a9D\3\2\2\2\u01aa\u01ab\7t\2\2\u01ab\u01ac\7g\2\2\u01ac"+
"\u01ad\7v\2\2\u01ad\u01ae\7w\2\2\u01ae\u01af\7t\2\2\u01af\u01b0\7p\2\2"+
"\u01b0F\3\2\2\2\u01b1\u01b2\7d\2\2\u01b2\u01b3\7t\2\2\u01b3\u01b4\7g\2"+
"\2\u01b4\u01b5\7c\2\2\u01b5\u01b6\7m\2\2\u01b6H\3\2\2\2\u01b7\u01b8\7"+
"e\2\2\u01b8\u01b9\7q\2\2\u01b9\u01ba\7p\2\2\u01ba\u01bb\7v\2\2\u01bb\u01bc"+
"\7k\2\2\u01bc\u01bd\7p\2\2\u01bd\u01be\7w\2\2\u01be\u01bf\7g\2\2\u01bf"+
"J\3\2\2\2\u01c0\u01c1\7c\2\2\u01c1\u01c2\7u\2\2\u01c2\u01c3\7o\2\2\u01c3"+
"L\3\2\2\2\u01c4\u01c5\7<\2\2\u01c5N\3\2\2\2\u01c6\u01c7\7\60\2\2\u01c7"+
"\u01c8\7\60\2\2\u01c8P\3\2\2\2\u01c9\u01ca\7u\2\2\u01ca\u01cb\7k\2\2\u01cb"+
"\u01cc\7i\2\2\u01cc\u01cd\7p\2\2\u01cd\u01ce\7g\2\2\u01ce\u01cf\7f\2\2"+
"\u01cfR\3\2\2\2\u01d0\u01d1\7w\2\2\u01d1\u01d2\7p\2\2\u01d2\u01d3\7u\2"+
"\2\u01d3\u01d4\7k\2\2\u01d4\u01d5\7i\2\2\u01d5\u01d6\7p\2\2\u01d6\u01d7"+
"\7g\2\2\u01d7\u01d8\7f\2\2\u01d8T\3\2\2\2\u01d9\u01da\7,\2\2\u01daV\3"+
"\2\2\2\u01db\u01dc\7]\2\2\u01dcX\3\2\2\2\u01dd\u01de\7_\2\2\u01deZ\3\2"+
"\2\2\u01df\u01e0\7u\2\2\u01e0\u01e1\7v\2\2\u01e1\u01e2\7t\2\2\u01e2\u01e3"+
"\7w\2\2\u01e3\u01e4\7e\2\2\u01e4\u01e5\7v\2\2\u01e5\\\3\2\2\2\u01e6\u01e7"+
"\7g\2\2\u01e7\u01e8\7p\2\2\u01e8\u01e9\7w\2\2\u01e9\u01ea\7o\2\2\u01ea"+
"^\3\2\2\2\u01eb\u01ec\7\60\2\2\u01ec`\3\2\2\2\u01ed\u01ee\7/\2\2\u01ee"+
"\u01ef\7@\2\2\u01efb\3\2\2\2\u01f0\u01f1\7u\2\2\u01f1\u01f2\7k\2\2\u01f2"+
"\u01f3\7|\2\2\u01f3\u01f4\7g\2\2\u01f4\u01f5\7q\2\2\u01f5\u01f6\7h\2\2"+
"\u01f6d\3\2\2\2\u01f7\u01f8\7v\2\2\u01f8\u01f9\7{\2\2\u01f9\u01fa\7r\2"+
"\2\u01fa\u01fb\7g\2\2\u01fb\u01fc\7k\2\2\u01fc\u01fd\7f\2\2\u01fdf\3\2"+
"\2\2\u01fe\u01ff\7/\2\2\u01ff\u0200\7/\2\2\u0200h\3\2\2\2\u0201\u0202"+
"\7-\2\2\u0202\u0203\7-\2\2\u0203j\3\2\2\2\u0204\u0205\7-\2\2\u0205l\3"+
"\2\2\2\u0206\u0207\7/\2\2\u0207n\3\2\2\2\u0208\u0209\7#\2\2\u0209p\3\2"+
"\2\2\u020a\u020b\7(\2\2\u020br\3\2\2\2\u020c\u020d\7\u0080\2\2\u020dt"+
"\3\2\2\2\u020e\u020f\7@\2\2\u020f\u0210\7@\2\2\u0210v\3\2\2\2\u0211\u0212"+
"\7>\2\2\u0212\u0213\7>\2\2\u0213x\3\2\2\2\u0214\u0215\7\61\2\2\u0215z"+
"\3\2\2\2\u0216\u0217\7\'\2\2\u0217|\3\2\2\2\u0218\u0219\7>\2\2\u0219~"+
"\3\2\2\2\u021a\u021b\7@\2\2\u021b\u0080\3\2\2\2\u021c\u021d\7?\2\2\u021d"+
"\u021e\7?\2\2\u021e\u0082\3\2\2\2\u021f\u0220\7#\2\2\u0220\u0221\7?\2"+
"\2\u0221\u0084\3\2\2\2\u0222\u0223\7>\2\2\u0223\u0224\7?\2\2\u0224\u0086"+
"\3\2\2\2\u0225\u0226\7@\2\2\u0226\u0227\7?\2\2\u0227\u0088\3\2\2\2\u0228"+
"\u0229\7`\2\2\u0229\u008a\3\2\2\2\u022a\u022b\7~\2\2\u022b\u008c\3\2\2"+
"\2\u022c\u022d\7(\2\2\u022d\u022e\7(\2\2\u022e\u008e\3\2\2\2\u022f\u0230"+
"\7~\2\2\u0230\u0231\7~\2\2\u0231\u0090\3\2\2\2\u0232\u0233\7A\2\2\u0233"+
"\u0092\3\2\2\2\u0234\u0235\7-\2\2\u0235\u0236\7?\2\2\u0236\u0094\3\2\2"+
"\2\u0237\u0238\7/\2\2\u0238\u0239\7?\2\2\u0239\u0096\3\2\2\2\u023a\u023b"+
"\7,\2\2\u023b\u023c\7?\2\2\u023c\u0098\3\2\2\2\u023d\u023e\7\61\2\2\u023e"+
"\u023f\7?\2\2\u023f\u009a\3\2\2\2\u0240\u0241\7\'\2\2\u0241\u0242\7?\2"+
"\2\u0242\u009c\3\2\2\2\u0243\u0244\7>\2\2\u0244\u0245\7>\2\2\u0245\u0246"+
"\7?\2\2\u0246\u009e\3\2\2\2\u0247\u0248\7@\2\2\u0248\u0249\7@\2\2\u0249"+
"\u024a\7?\2\2\u024a\u00a0\3\2\2\2\u024b\u024c\7(\2\2\u024c\u024d\7?\2"+
"\2\u024d\u00a2\3\2\2\2\u024e\u024f\7~\2\2\u024f\u0250\7?\2\2\u0250\u00a4"+
"\3\2\2\2\u0251\u0252\7`\2\2\u0252\u0253\7?\2\2\u0253\u00a6\3\2\2\2\u0254"+
"\u0255\7m\2\2\u0255\u0256\7k\2\2\u0256\u0257\7e\2\2\u0257\u0258\7m\2\2"+
"\u0258\u0259\7c\2\2\u0259\u025a\7u\2\2\u025a\u025b\7o\2\2\u025b\u00a8"+
"\3\2\2\2\u025c\u025d\7t\2\2\u025d\u025e\7g\2\2\u025e\u025f\7u\2\2\u025f"+
"\u0260\7q\2\2\u0260\u0261\7w\2\2\u0261\u0262\7t\2\2\u0262\u0263\7e\2\2"+
"\u0263\u0264\7g\2\2\u0264\u00aa\3\2\2\2\u0265\u0266\7w\2\2\u0266\u0267"+
"\7u\2\2\u0267\u0268\7g\2\2\u0268\u0269\7u\2\2\u0269\u00ac\3\2\2\2\u026a"+
"\u026b\7e\2\2\u026b\u026c\7n\2\2\u026c\u026d\7q\2\2\u026d\u026e\7d\2\2"+
"\u026e\u026f\7d\2\2\u026f\u0270\7g\2\2\u0270\u0271\7t\2\2\u0271\u0272"+
"\7u\2\2\u0272\u00ae\3\2\2\2\u0273\u0274\7d\2\2\u0274\u0275\7{\2\2\u0275"+
"\u0276\7v\2\2\u0276\u0277\7g\2\2\u0277\u0278\7u\2\2\u0278\u00b0\3\2\2"+
"\2\u0279\u027a\7e\2\2\u027a\u027b\7{\2\2\u027b\u027c\7e\2\2\u027c\u027d"+
"\7n\2\2\u027d\u027e\7g\2\2\u027e\u027f\7u\2\2\u027f\u00b2\3\2\2\2\u0280"+
"\u0281\7\60\2\2\u0281\u0282\7d\2\2\u0282\u0283\7{\2\2\u0283\u0284\7v\2"+
"\2\u0284\u0285\7g\2\2\u0285\u00b4\3\2\2\2\u0286\u0287\7%\2\2\u0287\u00b6"+
"\3\2\2\2\u0288\u0289\7d\2\2\u0289\u028a\7t\2\2\u028a\u0367\7m\2\2\u028b"+
"\u028c\7q\2\2\u028c\u028d\7t\2\2\u028d\u0367\7c\2\2\u028e\u028f\7m\2\2"+
"\u028f\u0290\7k\2\2\u0290\u0367\7n\2\2\u0291\u0292\7u\2\2\u0292\u0293"+
"\7n\2\2\u0293\u0367\7q\2\2\u0294\u0295\7p\2\2\u0295\u0296\7q\2\2\u0296"+
"\u0367\7r\2\2\u0297\u0298\7c\2\2\u0298\u0299\7u\2\2\u0299\u0367\7n\2\2"+
"\u029a\u029b\7r\2\2\u029b\u029c\7j\2\2\u029c\u0367\7r\2\2\u029d\u029e"+
"\7c\2\2\u029e\u029f\7p\2\2\u029f\u0367\7e\2\2\u02a0\u02a1\7d\2\2\u02a1"+
"\u02a2\7r\2\2\u02a2\u0367\7n\2\2\u02a3\u02a4\7e\2\2\u02a4\u02a5\7n\2\2"+
"\u02a5\u0367\7e\2\2\u02a6\u02a7\7l\2\2\u02a7\u02a8\7u\2\2\u02a8\u0367"+
"\7t\2\2\u02a9\u02aa\7c\2\2\u02aa\u02ab\7p\2\2\u02ab\u0367\7f\2\2\u02ac"+
"\u02ad\7t\2\2\u02ad\u02ae\7n\2\2\u02ae\u0367\7c\2\2\u02af\u02b0\7d\2\2"+
"\u02b0\u02b1\7k\2\2\u02b1\u0367\7v\2\2\u02b2\u02b3\7t\2\2\u02b3\u02b4"+
"\7q\2\2\u02b4\u0367\7n\2\2\u02b5\u02b6\7r\2\2\u02b6\u02b7\7n\2\2\u02b7"+
"\u0367\7c\2\2\u02b8\u02b9\7r\2\2\u02b9\u02ba\7n\2\2\u02ba\u0367\7r\2\2"+
"\u02bb\u02bc\7d\2\2\u02bc\u02bd\7o\2\2\u02bd\u0367\7k\2\2\u02be\u02bf"+
"\7u\2\2\u02bf\u02c0\7g\2\2\u02c0\u0367\7e\2\2\u02c1\u02c2\7t\2\2\u02c2"+
"\u02c3\7v\2\2\u02c3\u0367\7k\2\2\u02c4\u02c5\7g\2\2\u02c5\u02c6\7q\2\2"+
"\u02c6\u0367\7t\2\2\u02c7\u02c8\7u\2\2\u02c8\u02c9\7t\2\2\u02c9\u0367"+
"\7g\2\2\u02ca\u02cb\7n\2\2\u02cb\u02cc\7u\2\2\u02cc\u0367\7t\2\2\u02cd"+
"\u02ce\7r\2\2\u02ce\u02cf\7j\2\2\u02cf\u0367\7c\2\2\u02d0\u02d1\7c\2\2"+
"\u02d1\u02d2\7n\2\2\u02d2\u0367\7t\2\2\u02d3\u02d4\7l\2\2\u02d4\u02d5"+
"\7o\2\2\u02d5\u0367\7r\2\2\u02d6\u02d7\7d\2\2\u02d7\u02d8\7x\2\2\u02d8"+
"\u0367\7e\2\2\u02d9\u02da\7e\2\2\u02da\u02db\7n\2\2\u02db\u0367\7k\2\2"+
"\u02dc\u02dd\7t\2\2\u02dd\u02de\7v\2\2\u02de\u0367\7u\2\2\u02df\u02e0"+
"\7c\2\2\u02e0\u02e1\7f\2\2\u02e1\u0367\7e\2\2\u02e2\u02e3\7t\2\2\u02e3"+
"\u02e4\7t\2\2\u02e4\u0367\7c\2\2\u02e5\u02e6\7d\2\2\u02e6\u02e7\7x\2\2"+
"\u02e7\u0367\7u\2\2\u02e8\u02e9\7u\2\2\u02e9\u02ea\7g\2\2\u02ea\u0367"+
"\7k\2\2\u02eb\u02ec\7u\2\2\u02ec\u02ed\7c\2\2\u02ed\u0367\7z\2\2\u02ee"+
"\u02ef\7u\2\2\u02ef\u02f0\7v\2\2\u02f0\u0367\7{\2\2\u02f1\u02f2\7u\2\2"+
"\u02f2\u02f3\7v\2\2\u02f3\u0367\7c\2\2\u02f4\u02f5\7u\2\2\u02f5\u02f6"+
"\7v\2\2\u02f6\u0367\7z\2\2\u02f7\u02f8\7f\2\2\u02f8\u02f9\7g\2\2\u02f9"+
"\u0367\7{\2\2\u02fa\u02fb\7v\2\2\u02fb\u02fc\7z\2\2\u02fc\u0367\7c\2\2"+
"\u02fd\u02fe\7z\2\2\u02fe\u02ff\7c\2\2\u02ff\u0367\7c\2\2\u0300\u0301"+
"\7d\2\2\u0301\u0302\7e\2\2\u0302\u0367\7e\2\2\u0303\u0304\7c\2\2\u0304"+
"\u0305\7j\2\2\u0305\u0367\7z\2\2\u0306\u0307\7v\2\2\u0307\u0308\7{\2\2"+
"\u0308\u0367\7c\2\2\u0309\u030a\7v\2\2\u030a\u030b\7z\2\2\u030b\u0367"+
"\7u\2\2\u030c\u030d\7v\2\2\u030d\u030e\7c\2\2\u030e\u0367\7u\2\2\u030f"+
"\u0310\7u\2\2\u0310\u0311\7j\2\2\u0311\u0367\7{\2\2\u0312\u0313\7u\2\2"+
"\u0313\u0314\7j\2\2\u0314\u0367\7z\2\2\u0315\u0316\7n\2\2\u0316\u0317"+
"\7f\2\2\u0317\u0367\7{\2\2\u0318\u0319\7n\2\2\u0319\u031a\7f\2\2\u031a"+
"\u0367\7c\2\2\u031b\u031c\7n\2\2\u031c\u031d\7f\2\2\u031d\u0367\7z\2\2"+
"\u031e\u031f\7n\2\2\u031f\u0320\7c\2\2\u0320\u0367\7z\2\2\u0321\u0322"+
"\7v\2\2\u0322\u0323\7c\2\2\u0323\u0367\7{\2\2\u0324\u0325\7v\2\2\u0325"+
"\u0326\7c\2\2\u0326\u0367\7z\2\2\u0327\u0328\7d\2\2\u0328\u0329\7e\2\2"+
"\u0329\u0367\7u\2\2\u032a\u032b\7e\2\2\u032b\u032c\7n\2\2\u032c\u0367"+
"\7x\2\2\u032d\u032e\7v\2\2\u032e\u032f\7u\2\2\u032f\u0367\7z\2\2\u0330"+
"\u0331\7n\2\2\u0331\u0332\7c\2\2\u0332\u0367\7u\2\2\u0333\u0334\7e\2\2"+
"\u0334\u0335\7r\2\2\u0335\u0367\7{\2\2\u0336\u0337\7e\2\2\u0337\u0338"+
"\7o\2\2\u0338\u0367\7r\2\2\u0339\u033a\7e\2\2\u033a\u033b\7r\2\2\u033b"+
"\u0367\7z\2\2\u033c\u033d\7f\2\2\u033d\u033e\7e\2\2\u033e\u0367\7r\2\2"+
"\u033f\u0340\7f\2\2\u0340\u0341\7g\2\2\u0341\u0367\7e\2\2\u0342\u0343"+
"\7k\2\2\u0343\u0344\7p\2\2\u0344\u0367\7e\2\2\u0345\u0346\7c\2\2\u0346"+
"\u0347\7z\2\2\u0347\u0367\7u\2\2\u0348\u0349\7d\2\2\u0349\u034a\7p\2\2"+
"\u034a\u0367\7g\2\2\u034b\u034c\7e\2\2\u034c\u034d\7n\2\2\u034d\u0367"+
"\7f\2\2\u034e\u034f\7u\2\2\u034f\u0350\7d\2\2\u0350\u0367\7e\2\2\u0351"+
"\u0352\7k\2\2\u0352\u0353\7u\2\2\u0353\u0367\7e\2\2\u0354\u0355\7k\2\2"+
"\u0355\u0356\7p\2\2\u0356\u0367\7z\2\2\u0357\u0358\7d\2\2\u0358\u0359"+
"\7g\2\2\u0359\u0367\7s\2\2\u035a\u035b\7u\2\2\u035b\u035c\7g\2\2\u035c"+
"\u0367\7f\2\2\u035d\u035e\7f\2\2\u035e\u035f\7g\2\2\u035f\u0367\7z\2\2"+
"\u0360\u0361\7k\2\2\u0361\u0362\7p\2\2\u0362\u0367\7{\2\2\u0363\u0364"+
"\7t\2\2\u0364\u0365\7q\2\2\u0365\u0367\7t\2\2\u0366\u0288\3\2\2\2\u0366"+
"\u028b\3\2\2\2\u0366\u028e\3\2\2\2\u0366\u0291\3\2\2\2\u0366\u0294\3\2"+
"\2\2\u0366\u0297\3\2\2\2\u0366\u029a\3\2\2\2\u0366\u029d\3\2\2\2\u0366"+
"\u02a0\3\2\2\2\u0366\u02a3\3\2\2\2\u0366\u02a6\3\2\2\2\u0366\u02a9\3\2"+
"\2\2\u0366\u02ac\3\2\2\2\u0366\u02af\3\2\2\2\u0366\u02b2\3\2\2\2\u0366"+
"\u02b5\3\2\2\2\u0366\u02b8\3\2\2\2\u0366\u02bb\3\2\2\2\u0366\u02be\3\2"+
"\2\2\u0366\u02c1\3\2\2\2\u0366\u02c4\3\2\2\2\u0366\u02c7\3\2\2\2\u0366"+
"\u02ca\3\2\2\2\u0366\u02cd\3\2\2\2\u0366\u02d0\3\2\2\2\u0366\u02d3\3\2"+
"\2\2\u0366\u02d6\3\2\2\2\u0366\u02d9\3\2\2\2\u0366\u02dc\3\2\2\2\u0366"+
"\u02df\3\2\2\2\u0366\u02e2\3\2\2\2\u0366\u02e5\3\2\2\2\u0366\u02e8\3\2"+
"\2\2\u0366\u02eb\3\2\2\2\u0366\u02ee\3\2\2\2\u0366\u02f1\3\2\2\2\u0366"+
"\u02f4\3\2\2\2\u0366\u02f7\3\2\2\2\u0366\u02fa\3\2\2\2\u0366\u02fd\3\2"+
"\2\2\u0366\u0300\3\2\2\2\u0366\u0303\3\2\2\2\u0366\u0306\3\2\2\2\u0366"+
"\u0309\3\2\2\2\u0366\u030c\3\2\2\2\u0366\u030f\3\2\2\2\u0366\u0312\3\2"+
"\2\2\u0366\u0315\3\2\2\2\u0366\u0318\3\2\2\2\u0366\u031b\3\2\2\2\u0366"+
"\u031e\3\2\2\2\u0366\u0321\3\2\2\2\u0366\u0324\3\2\2\2\u0366\u0327\3\2"+
"\2\2\u0366\u032a\3\2\2\2\u0366\u032d\3\2\2\2\u0366\u0330\3\2\2\2\u0366"+
"\u0333\3\2\2\2\u0366\u0336\3\2\2\2\u0366\u0339\3\2\2\2\u0366\u033c\3\2"+
"\2\2\u0366\u033f\3\2\2\2\u0366\u0342\3\2\2\2\u0366\u0345\3\2\2\2\u0366"+
"\u0348\3\2\2\2\u0366\u034b\3\2\2\2\u0366\u034e\3\2\2\2\u0366\u0351\3\2"+
"\2\2\u0366\u0354\3\2\2\2\u0366\u0357\3\2\2\2\u0366\u035a\3\2\2\2\u0366"+
"\u035d\3\2\2\2\u0366\u0360\3\2\2\2\u0366\u0363\3\2\2\2\u0367\u00b8\3\2"+
"\2\2\u0368\u0369\7}\2\2\u0369\u036a\7}\2\2\u036a\u036e\3\2\2\2\u036b\u036d"+
"\13\2\2\2\u036c\u036b\3\2\2\2\u036d\u0370\3\2\2\2\u036e\u036f\3\2\2\2"+
"\u036e\u036c\3\2\2\2\u036f\u0371\3\2\2\2\u0370\u036e\3\2\2\2\u0371\u0372"+
"\7\177\2\2\u0372\u0373\7\177\2\2\u0373\u00ba\3\2\2\2\u0374\u0375\7d\2"+
"\2\u0375\u0376\7{\2\2\u0376\u0377\7v\2\2\u0377\u039a\7g\2\2\u0378\u0379"+
"\7y\2\2\u0379\u037a\7q\2\2\u037a\u037b\7t\2\2\u037b\u039a\7f\2\2\u037c"+
"\u037d\7f\2\2\u037d\u037e\7y\2\2\u037e\u037f\7q\2\2\u037f\u0380\7t\2\2"+
"\u0380\u039a\7f\2\2\u0381\u0382\7d\2\2\u0382\u0383\7q\2\2\u0383\u0384"+
"\7q\2\2\u0384\u039a\7n\2\2\u0385\u0386\7e\2\2\u0386\u0387\7j\2\2\u0387"+
"\u0388\7c\2\2\u0388\u039a\7t\2\2\u0389\u038a\7u\2\2\u038a\u038b\7j\2\2"+
"\u038b\u038c\7q\2\2\u038c\u038d\7t\2\2\u038d\u039a\7v\2\2\u038e\u038f"+
"\7k\2\2\u038f\u0390\7p\2\2\u0390\u039a\7v\2\2\u0391\u0392\7n\2\2\u0392"+
"\u0393\7q\2\2\u0393\u0394\7p\2\2\u0394\u039a\7i\2\2\u0395\u0396\7x\2\2"+
"\u0396\u0397\7q\2\2\u0397\u0398\7k\2\2\u0398\u039a\7f\2\2\u0399\u0374"+
"\3\2\2\2\u0399\u0378\3\2\2\2\u0399\u037c\3\2\2\2\u0399\u0381\3\2\2\2\u0399"+
"\u0385\3\2\2\2\u0399\u0389\3\2\2\2\u0399\u038e\3\2\2\2\u0399\u0391\3\2"+
"\2\2\u0399\u0395\3\2\2\2\u039a\u00bc\3\2\2\2\u039b\u03a1\7$\2\2\u039c"+
"\u039d\7^\2\2\u039d\u03a0\7$\2\2\u039e\u03a0\n\2\2\2\u039f\u039c\3\2\2"+
"\2\u039f\u039e\3\2\2\2\u03a0\u03a3\3\2\2\2\u03a1\u039f\3\2\2\2\u03a1\u03a2"+
"\3\2\2\2\u03a2\u03a4\3\2\2\2\u03a3\u03a1\3\2\2\2\u03a4\u03a6\7$\2\2\u03a5"+
"\u03a7\t\3\2\2\u03a6\u03a5\3\2\2\2\u03a6\u03a7\3\2\2\2\u03a7\u03ac\3\2"+
"\2\2\u03a8\u03aa\t\4\2\2\u03a9\u03ab\t\5\2\2\u03aa\u03a9\3\2\2\2\u03aa"+
"\u03ab\3\2\2\2\u03ab\u03ad\3\2\2\2\u03ac\u03a8\3\2\2\2\u03ac\u03ad\3\2"+
"\2\2\u03ad\u03af\3\2\2\2\u03ae\u03b0\t\3\2\2\u03af\u03ae\3\2\2\2\u03af"+
"\u03b0\3\2\2\2\u03b0\u00be\3\2\2\2\u03b1\u03b5\7)\2\2\u03b2\u03b3\7^\2"+
"\2\u03b3\u03b6\7)\2\2\u03b4\u03b6\n\6\2\2\u03b5\u03b2\3\2\2\2\u03b5\u03b4"+
"\3\2\2\2\u03b6\u03b7\3\2\2\2\u03b7\u03b8\7)\2\2\u03b8\u00c0\3\2\2\2\u03b9"+
"\u03ba\7v\2\2\u03ba\u03bb\7t\2\2\u03bb\u03bc\7w\2\2\u03bc\u03c3\7g\2\2"+
"\u03bd\u03be\7h\2\2\u03be\u03bf\7c\2\2\u03bf\u03c0\7n\2\2\u03c0\u03c1"+
"\7u\2\2\u03c1\u03c3\7g\2\2\u03c2\u03b9\3\2\2\2\u03c2\u03bd\3\2\2\2\u03c3"+
"\u00c2\3\2\2\2\u03c4\u03c7\5\u00c5c\2\u03c5\u03c7\5\u00cdg\2\u03c6\u03c4"+
"\3\2\2\2\u03c6\u03c5\3\2\2\2\u03c7\u00c4\3\2\2\2\u03c8\u03cc\5\u00c7d"+
"\2\u03c9\u03cc\5\u00c9e\2\u03ca\u03cc\5\u00cbf\2\u03cb\u03c8\3\2\2\2\u03cb"+
"\u03c9\3\2\2\2\u03cb\u03ca\3\2\2\2\u03cc\u00c6\3\2\2\2\u03cd\u03d3\7\'"+
"\2\2\u03ce\u03cf\7\62\2\2\u03cf\u03d3\7d\2\2\u03d0\u03d1\7\62\2\2\u03d1"+
"\u03d3\7D\2\2\u03d2\u03cd\3\2\2\2\u03d2\u03ce\3\2\2\2\u03d2\u03d0\3\2"+
"\2\2\u03d3\u03d7\3\2\2\2\u03d4\u03d6\5\u00d5k\2\u03d5\u03d4\3\2\2\2\u03d6"+
"\u03d9\3\2\2\2\u03d7\u03d5\3\2\2\2\u03d7\u03d8\3\2\2\2\u03d8\u03da\3\2"+
"\2\2\u03d9\u03d7\3\2\2\2\u03da\u03dc\7\60\2\2\u03db\u03dd\5\u00d5k\2\u03dc"+
"\u03db\3\2\2\2\u03dd\u03de\3\2\2\2\u03de\u03dc\3\2\2\2\u03de\u03df\3\2"+
"\2\2\u03df\u00c8\3\2\2\2\u03e0\u03e2\5\u00d7l\2\u03e1\u03e0\3\2\2\2\u03e2"+
"\u03e5\3\2\2\2\u03e3\u03e1\3\2\2\2\u03e3\u03e4\3\2\2\2\u03e4\u03e6\3\2"+
"\2\2\u03e5\u03e3\3\2\2\2\u03e6\u03e8\7\60\2\2\u03e7\u03e9\5\u00d7l\2\u03e8"+
"\u03e7\3\2\2\2\u03e9\u03ea\3\2\2\2\u03ea\u03e8\3\2\2\2\u03ea\u03eb\3\2"+
"\2\2\u03eb\u00ca\3\2\2\2\u03ec\u03f2\7&\2\2\u03ed\u03ee\7\62\2\2\u03ee"+
"\u03f2\7z\2\2\u03ef\u03f0\7\62\2\2\u03f0\u03f2\7Z\2\2\u03f1\u03ec\3\2"+
"\2\2\u03f1\u03ed\3\2\2\2\u03f1\u03ef\3\2\2\2\u03f2\u03f6\3\2\2\2\u03f3"+
"\u03f5\5\u00d9m\2\u03f4\u03f3\3\2\2\2\u03f5\u03f8\3\2\2\2\u03f6\u03f4"+
"\3\2\2\2\u03f6\u03f7\3\2\2\2\u03f7\u03f9\3\2\2\2\u03f8\u03f6\3\2\2\2\u03f9"+
"\u03fb\7\60\2\2\u03fa\u03fc\5\u00d9m\2\u03fb\u03fa\3\2\2\2\u03fc\u03fd"+
"\3\2\2\2\u03fd\u03fb\3\2\2\2\u03fd\u03fe\3\2\2\2\u03fe\u00cc\3\2\2\2\u03ff"+
"\u0403\5\u00d1i\2\u0400\u0403\5\u00d3j\2\u0401\u0403\5\u00cfh\2\u0402"+
"\u03ff\3\2\2\2\u0402\u0400\3\2\2\2\u0402\u0401\3\2\2\2\u0403\u0407\3\2"+
"\2\2\u0404\u0405\t\7\2\2\u0405\u0408\t\b\2\2\u0406\u0408\7n\2\2\u0407"+
"\u0404\3\2\2\2\u0407\u0406\3\2\2\2\u0407\u0408\3\2\2\2\u0408\u00ce\3\2"+
"\2\2\u0409\u040a\7\62\2\2\u040a\u040c\t\t\2\2\u040b\u040d\5\u00d5k\2\u040c"+
"\u040b\3\2\2\2\u040d\u040e\3\2\2\2\u040e\u040c\3\2\2\2\u040e\u040f\3\2"+
"\2\2\u040f\u0417\3\2\2\2\u0410\u0412\7\'\2\2\u0411\u0413\5\u00d5k\2\u0412"+
"\u0411\3\2\2\2\u0413\u0414\3\2\2\2\u0414\u0412\3\2\2\2\u0414\u0415\3\2"+
"\2\2\u0415\u0417\3\2\2\2\u0416\u0409\3\2\2\2\u0416\u0410\3\2\2\2\u0417"+
"\u00d0\3\2\2\2\u0418\u041a\5\u00d7l\2\u0419\u0418\3\2\2\2\u041a\u041b"+
"\3\2\2\2\u041b\u0419\3\2\2\2\u041b\u041c\3\2\2\2\u041c\u00d2\3\2\2\2\u041d"+
"\u0423\7&\2\2\u041e\u041f\7\62\2\2\u041f\u0423\7z\2\2\u0420\u0421\7\62"+
"\2\2\u0421\u0423\7Z\2\2\u0422\u041d\3\2\2\2\u0422\u041e\3\2\2\2\u0422"+
"\u0420\3\2\2\2\u0423\u0425\3\2\2\2\u0424\u0426\5\u00d9m\2\u0425\u0424"+
"\3\2\2\2\u0426\u0427\3\2\2\2\u0427\u0425\3\2\2\2\u0427\u0428\3\2\2\2\u0428"+
"\u00d4\3\2\2\2\u0429\u042a\t\n\2\2\u042a\u00d6\3\2\2\2\u042b\u042c\t\13"+
"\2\2\u042c\u00d8\3\2\2\2\u042d\u042e\t\f\2\2\u042e\u00da\3\2\2\2\u042f"+
"\u0433\5\u00ddo\2\u0430\u0432\5\u00dfp\2\u0431\u0430\3\2\2\2\u0432\u0435"+
"\3\2\2\2\u0433\u0431\3\2\2\2\u0433\u0434\3\2\2\2\u0434\u00dc\3\2\2\2\u0435"+
"\u0433\3\2\2\2\u0436\u0437\t\r\2\2\u0437\u00de\3\2\2\2\u0438\u0439\t\16"+
"\2\2\u0439\u00e0\3\2\2\2\u043a\u043e\7#\2\2\u043b\u043d\5\u00dfp\2\u043c"+
"\u043b\3\2\2\2\u043d\u0440\3\2\2\2\u043e\u043c\3\2\2\2\u043e\u043f\3\2"+
"\2\2\u043f\u0442\3\2\2\2\u0440\u043e\3\2\2\2\u0441\u0443\t\17\2\2\u0442"+
"\u0441\3\2\2\2\u0443\u0444\3\2\2\2\u0444\u0442\3\2\2\2\u0444\u0445\3\2"+
"\2\2\u0445\u00e2\3\2\2\2\u0446\u0448\t\20\2\2\u0447\u0446\3\2\2\2\u0448"+
"\u0449\3\2\2\2\u0449\u0447\3\2\2\2\u0449\u044a\3\2\2\2\u044a\u044b\3\2"+
"\2\2\u044b\u044c\br\2\2\u044c\u00e4\3\2\2\2\u044d\u044e\7\61\2\2\u044e"+
"\u044f\7\61\2\2\u044f\u0453\3\2\2\2\u0450\u0452\n\21\2\2\u0451\u0450\3"+
"\2\2\2\u0452\u0455\3\2\2\2\u0453\u0451\3\2\2\2\u0453\u0454\3\2\2\2\u0454"+
"\u0456\3\2\2\2\u0455\u0453\3\2\2\2\u0456\u0457\bs\3\2\u0457\u00e6\3\2"+
"\2\2\u0458\u0459\7\61\2\2\u0459\u045a\7,\2\2\u045a\u045e\3\2\2\2\u045b"+
"\u045d\13\2\2\2\u045c\u045b\3\2\2\2\u045d\u0460\3\2\2\2\u045e\u045f\3"+
"\2\2\2\u045e\u045c\3\2\2\2\u045f\u0461\3\2\2\2\u0460\u045e\3\2\2\2\u0461"+
"\u0462\7,\2\2\u0462\u0463\7\61\2\2\u0463\u0464\3\2\2\2\u0464\u0465\bt"+
"\3\2\u0465\u00e8\3\2\2\2&\2\u0366\u036e\u0399\u039f\u03a1\u03a6\u03aa"+
"\u03ac\u03af\u03b5\u03c2\u03c6\u03cb\u03d2\u03d7\u03de\u03e3\u03ea\u03f1"+
"\u03f6\u03fd\u0402\u0407\u040e\u0414\u0416\u041b\u0422\u0427\u0433\u043e"+
"\u0444\u0449\u0453\u045e\4\2\3\2\2\4\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -87,26 +87,27 @@ T__85=86
T__86=87
T__87=88
T__88=89
MNEMONIC=90
KICKASM=91
SIMPLETYPE=92
STRING=93
CHAR=94
BOOLEAN=95
NUMBER=96
NUMFLOAT=97
BINFLOAT=98
DECFLOAT=99
HEXFLOAT=100
NUMINT=101
BININTEGER=102
DECINTEGER=103
HEXINTEGER=104
NAME=105
ASMREL=106
WS=107
COMMENT_LINE=108
COMMENT_BLOCK=109
T__89=90
MNEMONIC=91
KICKASM=92
SIMPLETYPE=93
STRING=94
CHAR=95
BOOLEAN=96
NUMBER=97
NUMFLOAT=98
BINFLOAT=99
DECFLOAT=100
HEXFLOAT=101
NUMINT=102
BININTEGER=103
DECINTEGER=104
HEXINTEGER=105
NAME=106
ASMREL=107
WS=108
COMMENT_LINE=109
COMMENT_BLOCK=110
'import'=1
';'=2
'typedef'=3
@ -124,75 +125,76 @@ COMMENT_BLOCK=109
'target'=15
'#target'=16
'link'=17
'#link'=18
'encoding'=19
'#encoding'=20
'const'=21
'extern'=22
'align'=23
'register'=24
'inline'=25
'volatile'=26
'interrupt'=27
'if'=28
'else'=29
'while'=30
'do'=31
'for'=32
'return'=33
'break'=34
'continue'=35
'asm'=36
':'=37
'..'=38
'signed'=39
'unsigned'=40
'*'=41
'['=42
']'=43
'struct'=44
'enum'=45
'.'=46
'->'=47
'sizeof'=48
'typeid'=49
'--'=50
'++'=51
'+'=52
'-'=53
'!'=54
'&'=55
'~'=56
'>>'=57
'<<'=58
'/'=59
'%'=60
'<'=61
'>'=62
'=='=63
'!='=64
'<='=65
'>='=66
'^'=67
'|'=68
'&&'=69
'||'=70
'?'=71
'+='=72
'-='=73
'*='=74
'/='=75
'%='=76
'<<='=77
'>>='=78
'&='=79
'|='=80
'^='=81
'kickasm'=82
'resource'=83
'uses'=84
'clobbers'=85
'bytes'=86
'cycles'=87
'.byte'=88
'#'=89
'code_seg'=18
'data_seg'=19
'encoding'=20
'#encoding'=21
'const'=22
'extern'=23
'align'=24
'register'=25
'inline'=26
'volatile'=27
'interrupt'=28
'if'=29
'else'=30
'while'=31
'do'=32
'for'=33
'return'=34
'break'=35
'continue'=36
'asm'=37
':'=38
'..'=39
'signed'=40
'unsigned'=41
'*'=42
'['=43
']'=44
'struct'=45
'enum'=46
'.'=47
'->'=48
'sizeof'=49
'typeid'=50
'--'=51
'++'=52
'+'=53
'-'=54
'!'=55
'&'=56
'~'=57
'>>'=58
'<<'=59
'/'=60
'%'=61
'<'=62
'>'=63
'=='=64
'!='=65
'<='=66
'>='=67
'^'=68
'|'=69
'&&'=70
'||'=71
'?'=72
'+='=73
'-='=74
'*='=75
'/='=76
'%='=77
'<<='=78
'>>='=79
'&='=80
'|='=81
'^='=82
'kickasm'=83
'resource'=84
'uses'=85
'clobbers'=86
'bytes'=87
'cycles'=88
'.byte'=89
'#'=90

View File

@ -1,4 +1,4 @@
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7.2
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
package dk.camelot64.kickc.parser;
import org.antlr.v4.runtime.tree.ParseTreeListener;
@ -223,6 +223,30 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx);
/**
* Enter a parse tree produced by the {@code globalDirectiveCodeSeg}
* labeled alternative in {@link KickCParser#globalDirective}.
* @param ctx the parse tree
*/
void enterGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx);
/**
* Exit a parse tree produced by the {@code globalDirectiveCodeSeg}
* labeled alternative in {@link KickCParser#globalDirective}.
* @param ctx the parse tree
*/
void exitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx);
/**
* Enter a parse tree produced by the {@code globalDirectiveDataSeg}
* labeled alternative in {@link KickCParser#globalDirective}.
* @param ctx the parse tree
*/
void enterGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx);
/**
* Exit a parse tree produced by the {@code globalDirectiveDataSeg}
* labeled alternative in {@link KickCParser#globalDirective}.
* @param ctx the parse tree
*/
void exitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx);
/**
* Enter a parse tree produced by the {@code globalDirectiveEncoding}
* labeled alternative in {@link KickCParser#globalDirective}.

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7.2
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7
package dk.camelot64.kickc.parser;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
@ -138,6 +138,20 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx);
/**
* Visit a parse tree produced by the {@code globalDirectiveCodeSeg}
* labeled alternative in {@link KickCParser#globalDirective}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx);
/**
* Visit a parse tree produced by the {@code globalDirectiveDataSeg}
* labeled alternative in {@link KickCParser#globalDirective}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx);
/**
* Visit a parse tree produced by the {@code globalDirectiveEncoding}
* labeled alternative in {@link KickCParser#globalDirective}.

View File

@ -163,20 +163,38 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
return null;
}
/** The current code segment - if null the default segment is used. */
String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
@Override
public Object visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) {
this.currentCodeSegment = ctx.NAME().getText();
return null;
}
/** The current data segment - if null the default segment is used. */
String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
@Override
public Object visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) {
this.currentDataSegment = ctx.NAME().getText();
return null;
}
@Override
public Object visitDeclFunction(KickCParser.DeclFunctionContext ctx) {
this.visitDeclTypes(ctx.declTypes());
SymbolType type = declVarType;
List<Directive> directives = declVarDirectives;
String name = ctx.NAME().getText();
Procedure procedure = getCurrentScope().addProcedure(name, type);
Procedure procedure = getCurrentScope().addProcedure(name, type, currentCodeSegment, currentDataSegment);
addDirectives(procedure, directives, StatementSource.procedureBegin(ctx));
procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx)));
scopeStack.push(procedure);
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
VariableUnversioned returnVar = null;
if(!SymbolType.VOID.equals(type)) {
returnVar = procedure.addVariable("return", type);
returnVar = procedure.addVariable("return", type, procedure.getSegmentData());
}
List<Variable> parameterList = new ArrayList<>();
if(ctx.parameterListDecl() != null) {
@ -229,7 +247,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
this.visitDeclTypes(ctx.declTypes());
SymbolType type = declVarType;
List<Directive> directives = declVarDirectives;
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type);
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment);
// Add directives
addDirectives(param, type, directives, new StatementSource(ctx));
exitDeclTypes();
@ -354,17 +372,17 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
/** KickAssembler directive specifying a constant used by the kickasm code. */
public static class AsmDirectiveUses implements AsmDirective {
/** constant/variable used by the KickAssembler-code. */
private SymbolVariableRef uses;
private SymbolRef uses;
public SymbolVariableRef getUses() {
public SymbolRef getUses() {
return uses;
}
AsmDirectiveUses(SymbolVariableRef uses) {
AsmDirectiveUses(SymbolRef uses) {
this.uses = uses;
}
public void setUses(SymbolVariableRef uses) {
public void setUses(SymbolRef uses) {
this.uses = uses;
}
@ -378,12 +396,11 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public Object visitAsmDirectiveUses(KickCParser.AsmDirectiveUsesContext ctx) {
String varName = ctx.NAME().getText();
SymbolVariableRef variableRef;
SymbolRef variableRef;
Symbol symbol = getCurrentScope().getSymbol(varName);
if(symbol instanceof Variable) {
if(symbol!=null) {
//Found an existing variable
Variable variable = (Variable) symbol;
variableRef = variable.getRef();
variableRef = symbol.getRef();
} else {
// Either forward reference or a non-existing variable. Create a forward reference for later resolving.
variableRef = new ForwardVariableRef(varName);
@ -557,9 +574,6 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
// Add KickAsm statement
StatementKickAsm kasm = (StatementKickAsm) this.visit(ctx.declKasm());
if(kasm.getUses().size() > 0) {
throw new CompileError("KickAsm initializers does not support 'uses' directive.", new StatementSource(ctx));
}
if(kasm.getLocation() != null) {
throw new CompileError("KickAsm initializers does not support 'location' directive.", new StatementSource(ctx));
}
@ -572,7 +586,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
if(kasm.getDeclaredClobber() != null) {
throw new CompileError("KickAsm initializers does not support 'clobbers' directive.", new StatementSource(ctx));
}
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypeArray) type).getElementType(), kasm.getKickAsmCode());
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypeArray) type).getElementType(), kasm.getKickAsmCode(), kasm.getUses());
// Remove the KickAsm statement
sequence.getStatements().remove(sequence.getStatements().size() - 1);
// Add an initializer statement instead
@ -588,7 +602,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
VariableUnversioned lValue;
try {
lValue = getCurrentScope().addVariable(varName, type);
lValue = getCurrentScope().addVariable(varName, type, currentDataSegment);
} catch(CompileError e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx));
}
@ -1026,7 +1040,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
Variable lValue;
if(varType != null) {
try {
lValue = getCurrentScope().addVariable(varName, varType);
lValue = getCurrentScope().addVariable(varName, varType, currentDataSegment);
} catch(CompileError e) {
throw new CompileError(e.getMessage(), statementSource);
}
@ -1327,7 +1341,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
Scope parentScope = getCurrentScope();
while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope();
for(ConstantVar member : enumDefinition.getAllConstants(false)) {
parentScope.add(new ConstantVar(member.getLocalName(), parentScope, SymbolType.BYTE, member.getValue()));
parentScope.add(new ConstantVar(member.getLocalName(), parentScope, SymbolType.BYTE, member.getValue(), currentDataSegment));
}
return SymbolType.BYTE;
} catch(CompileError e) {
@ -1361,7 +1375,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
}
}
currentEnum.add(new ConstantVar(memberName, getCurrentScope(), SymbolType.BYTE, enumValue));
currentEnum.add(new ConstantVar(memberName, getCurrentScope(), SymbolType.BYTE, enumValue, currentDataSegment));
return null;
}

View File

@ -60,7 +60,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
name = nameHint + nameHintIdx++;
}
}
ConstantVar strConst = new ConstantVar(name, blockScope, SymbolType.STRING, constantString);
ConstantVar strConst = new ConstantVar(name, blockScope, SymbolType.STRING, constantString, blockScope.getSegmentData());
blockScope.add(strConst);
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");

View File

@ -295,7 +295,7 @@ public class Pass1ProcedureInline extends Pass1Base {
if(procSymbol instanceof Variable) {
Variable procVar = (Variable) procSymbol;
String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial);
VariableUnversioned inlineVar = callScope.addVariable(inlineVarName, procSymbol.getType());
VariableUnversioned inlineVar = callScope.addVariable(inlineVarName, procSymbol.getType(), procVar.getDataSegment());
inlineVar.setInferredType(procVar.isInferredType());
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
inlineVar.setDeclaredConstant(procVar.isDeclaredConstant());

View File

@ -26,7 +26,7 @@ public class Pass1ResolveForwardReferences extends Pass1Base {
Symbol symbol = currentScope.getSymbol(varName);
if(symbol!=null) {
getLog().append("Resolved forward reference " + varName+" to "+symbol.toString(getProgram()));
programValue.set((RValue) symbol.getRef());
programValue.set(symbol.getRef());
} else {
getLog().append("ERROR! Unknown variable " + varName);
throw new CompileError("ERROR! Unknown variable " + varName, currentStmt.getSource());

View File

@ -69,12 +69,13 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
}
} else if(symbol instanceof VariableUnversioned) {
String name = findLocalName(procedure, symbol);
VariableUnversioned unwound = procedure.addVariable(name, symbol.getType());
unwound.setDeclaredAlignment(((VariableUnversioned) symbol).getDeclaredAlignment());
unwound.setDeclaredConstant(((VariableUnversioned) symbol).isDeclaredConstant());
unwound.setDeclaredVolatile(((VariableUnversioned) symbol).isDeclaredVolatile());
unwound.setInferedVolatile(((VariableUnversioned) symbol).isInferedVolatile());
unwound.setDeclaredRegister((((VariableUnversioned) symbol).getDeclaredRegister()));
VariableUnversioned var = (VariableUnversioned) symbol;
VariableUnversioned unwound = procedure.addVariable(name, symbol.getType(), var.getDataSegment());
unwound.setDeclaredAlignment(var.getDeclaredAlignment());
unwound.setDeclaredConstant(var.isDeclaredConstant());
unwound.setDeclaredVolatile(var.isDeclaredVolatile());
unwound.setInferedVolatile(var.isInferedVolatile());
unwound.setDeclaredRegister((var.getDeclaredRegister()));
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
} else if(symbol instanceof VariableIntermediate) {
VariableIntermediate unwound = procedure.addVariableIntermediate();

View File

@ -212,9 +212,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
for(Variable member : structDefinition.getAllVariables(false)) {
Variable memberVariable;
if(variable.getRef().isIntermediate()) {
memberVariable = scope.add(new VariableIntermediate(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType()));
memberVariable = scope.add(new VariableIntermediate(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), variable.getDataSegment()));
} else {
memberVariable = scope.addVariable(variable.getLocalName() + "_" + member.getLocalName(), member.getType());
memberVariable = scope.addVariable(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), variable.getDataSegment());
}
memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile());
memberVariable.setInferedVolatile(variable.isInferedVolatile());

View File

@ -75,7 +75,10 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
variable.getName(),
constScope,
variableType,
constVal);
constVal,
variable.getDataSegment()
);
constantVar.setInferredType(variable.isInferredType());
constantVar.setDeclaredAlignment(variable.getDeclaredAlignment());
constantVar.setDeclaredRegister(variable.getDeclaredRegister());

View File

@ -63,8 +63,10 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
ConstantVar rootConstant = null;
boolean isCommonScope = true;
ScopeRef commonScope = null;
String segmentData = null;
for(ConstantVar constantVar : constantVars) {
ScopeRef constScope = constantVar.getScope().getRef();
segmentData = constantVar.getDataSegment();
if(constScope.equals(ScopeRef.ROOT)) {
rootConstant = constantVar;
break;
@ -87,7 +89,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
// Create a new root - and roll around again
ProgramScope rootScope = getScope();
String localName = getRootName(constantVars);
ConstantVar newRootConstant = new ConstantVar(localName, rootScope, SymbolType.STRING, constString);
ConstantVar newRootConstant = new ConstantVar(localName, rootScope, SymbolType.STRING, constString, segmentData);
rootScope.add(newRootConstant);
rootConstant = newRootConstant;
}

View File

@ -6,10 +6,7 @@ import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAsm;
import dk.camelot64.kickc.model.statements.StatementKickAsm;
import dk.camelot64.kickc.model.values.ConstantRef;
import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.SymbolVariableRef;
import dk.camelot64.kickc.model.values.*;
import java.util.List;
import java.util.Map;
@ -56,8 +53,8 @@ public class Pass3AssertConstants extends Pass2SsaAssertion {
}
} else if(statement instanceof StatementKickAsm) {
StatementKickAsm statementAsm = (StatementKickAsm) statement;
List<SymbolVariableRef> uses = statementAsm.getUses();
for(SymbolVariableRef use : uses) {
List<SymbolRef> uses = statementAsm.getUses();
for(SymbolRef use : uses) {
if(!(use instanceof ConstantRef)) {
throw new CompileError("Error! Inline KickAsm reference is not constant " + use, statement);
}

View File

@ -83,14 +83,14 @@ public class Pass4CodeGeneration {
Number programPc = program.getProgramPc();
if(TargetPlatform.C64BASIC_SEGMENTS.equals(program.getTargetPlatform())) {
useSegments = true;
currentCodeSegmentName = "Code";
currentDataSegmentName = "Data";
currentCodeSegmentName = Scope.SEGMENT_CODE_DEFAULT;
currentDataSegmentName = Scope.SEGMENT_DATA_DEFAULT;
if(programPc==null) programPc = 0x080d;
asm.addLine(new AsmFile(outputPrgPath).param("type", "\"prg\"").param("segments", "\"Program\""));
asm.addLine(new AsmSegmentDef("Program").param("segments", "\"Basic,Code,Data\""));
asm.addLine(new AsmSegmentDef("Basic").param("start", "$0801"));
asm.addLine(new AsmSegmentDef("Code").param("start", AsmFormat.getAsmNumber(programPc)));
asm.addLine(new AsmSegmentDef("Data").param("startAfter", "\"Code\""));
asm.addLine(new AsmSegmentDef(Scope.SEGMENT_CODE_DEFAULT).param("start", AsmFormat.getAsmNumber(programPc)));
asm.addLine(new AsmSegmentDef(Scope.SEGMENT_DATA_DEFAULT).param("startAfter", "\"Code\""));
asm.addLine(new AsmSegment("Basic"));
asm.addLine(new AsmBasicUpstart("bbegin"));
setCurrentSegment(currentCodeSegmentName, asm);
@ -102,13 +102,13 @@ public class Pass4CodeGeneration {
asm.addLine(new AsmSetPc("Program", AsmFormat.getAsmNumber(programPc)));
} else if(TargetPlatform.ASM6502_SEGMENTS.equals(program.getTargetPlatform())) {
useSegments = true;
currentCodeSegmentName = "Code";
currentDataSegmentName = "Data";
currentCodeSegmentName = Scope.SEGMENT_CODE_DEFAULT;
currentDataSegmentName = Scope.SEGMENT_DATA_DEFAULT;
if(programPc==null) programPc = 0x2000;
asm.addLine(new AsmFile(outputPrgPath).param("type", "\"prg\"").param("segments", "\"Program\""));
asm.addLine(new AsmSegmentDef("Program").param("segments", "\"Code,Data\""));
asm.addLine(new AsmSegmentDef("Code").param("start", AsmFormat.getAsmNumber(programPc)));
asm.addLine(new AsmSegmentDef("Data").param("startAfter", "\"Code\""));
asm.addLine(new AsmSegmentDef(Scope.SEGMENT_CODE_DEFAULT).param("start", AsmFormat.getAsmNumber(programPc)));
asm.addLine(new AsmSegmentDef(Scope.SEGMENT_DATA_DEFAULT).param("startAfter", "\"Code\""));
setCurrentSegment(currentCodeSegmentName, asm);
} else if(TargetPlatform.ASM6502.equals(program.getTargetPlatform())) {
useSegments = false;
@ -133,6 +133,10 @@ public class Pass4CodeGeneration {
// The current block is in a different scope. End the old scope.
generateScopeEnding(asm, currentScope);
currentScope = block.getScope();
if(block.isProcedureEntry(program)) {
Procedure procedure = block.getProcedure(program);
currentCodeSegmentName = procedure.getCodeSegment();
}
setCurrentSegment(currentCodeSegmentName, asm);
asm.startChunk(currentScope, null, block.getLabel().getFullName());
// Add any procedure comments
@ -189,9 +193,6 @@ public class Pass4CodeGeneration {
currentScope = ScopeRef.ROOT;
asm.startChunk(currentScope, null, "File Data");
if(hasData(currentScope)) {
setCurrentSegment(currentDataSegmentName, asm);
}
addData(asm, ScopeRef.ROOT);
// Add all absolutely placed inline KickAsm
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
@ -214,11 +215,11 @@ public class Pass4CodeGeneration {
}
// Should the generated program use segments?
boolean useSegments = false;
private boolean useSegments = false;
// Name of the current data segment
private String currentCodeSegmentName = "Code";
private String currentCodeSegmentName = Scope.SEGMENT_CODE_DEFAULT;
// Name of the current code segment
private String currentDataSegmentName = "Data";
private String currentDataSegmentName = Scope.SEGMENT_DATA_DEFAULT;
// Name of the current active segment
private String currentSegmentName = "";
@ -255,9 +256,6 @@ public class Pass4CodeGeneration {
asm.addInstruction("jmp", AsmAddressingMode.IND, indirectCallAsmName, false);
}
indirectCallAsmNames = new ArrayList<>();
if(hasData(currentScope)) {
setCurrentSegment(currentDataSegmentName, asm);
}
addData(asm, currentScope);
asm.addScopeEnd();
}
@ -276,7 +274,6 @@ public class Pass4CodeGeneration {
asm.addInstruction("jsr", AsmAddressingMode.ABS, "bi_" + varAsmName, false);
}
/**
* Generate a comment that describes the procedure signature and parameter transfer
*
@ -448,23 +445,6 @@ public class Pass4CodeGeneration {
return useLabel;
}
/**
* Examine whether there are any data directives to be added
*
* @param scopeRef The scope
*/
private boolean hasData(ScopeRef scopeRef) {
Scope scope = program.getScope().getScope(scopeRef);
Collection<ConstantVar> scopeConstants = scope.getAllConstants(false);
for(ConstantVar constantVar : scopeConstants) {
if(hasData(constantVar)) {
return true;
}
}
return false;
}
/**
* Add data directives for constants declarations
*
@ -482,6 +462,8 @@ public class Pass4CodeGeneration {
if(added.contains(asmName)) {
continue;
}
// Set segment
setCurrentSegment(constantVar.getDataSegment(), asm);
// Add any comments
generateComments(asm, constantVar.getComments());
// Add any alignment

View File

@ -99,7 +99,7 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
// Constant not found - create it
Variable memberDef = structDefinition.getMember(memberName);
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef);
memberOffsetConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE));
memberOffsetConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(memberOffsetConstant);
}
return memberOffsetConstant.getRef();

View File

@ -36,6 +36,11 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testXMega65() throws IOException, URISyntaxException {
compileAndCompare("complex/xmega65/xmega65");
}
@Test
public void testLinking() throws IOException, URISyntaxException {
compileAndCompare("examples/linking/linking");

View File

@ -0,0 +1,23 @@
// Example showing how to perform linking using a linker-file
// The linker file is created using KickAssembler segments.
// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
#pragma link("xmega65.ld")
char* BGCOL = 0xd021;
void main() {
while(true) {
*BGCOL = SYSCALLS[0];
(*BGCOL)++;
}
}
#pragma data_seg(Syscall)
byte[] SYSCALLS = kickasm {{
jmp main
nop
}};

View File

@ -4,12 +4,30 @@
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
#pragma link("xmega65.ld")
#pragma link("linking.ld")
char* BGCOL = 0xd021;
void main() {
for(char i:0..255)
base[i] = i;
while(true) {
fillscreen(*BGCOL);
(*BGCOL)++;
}
}
}
#pragma code_seg(CodeHigh)
#pragma data_seg(DataHigh)
byte* SCREEN = 0x0400;
void fillscreen(char c) {
char i = 0;
for( char *screen = SCREEN; screen<SCREEN+1000; screen++)
*screen = c+base[i++];
}
byte[256] base;

View File

@ -0,0 +1,10 @@
.file [name="%O.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, CodeHigh, DataHigh"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef CodeHigh [start=$4000]
.segmentdef DataHigh [startAfter="CodeHigh"]
.segment Basic
:BasicUpstart(main)

View File

@ -0,0 +1,26 @@
// Example showing how to perform linking using a linker-file
// The linker file is created using KickAssembler segments.
// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
.file [name="xmega65.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
.label BGCOL = $d021
.segment Code
main: {
b1:
lda SYSCALLS
sta BGCOL
inc BGCOL
jmp b1
}
.segment Syscall
SYSCALLS:
jmp main
nop

View File

@ -0,0 +1,16 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0)
[6] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0)
to:main::@1

View File

@ -0,0 +1,309 @@
Loading link script "xmega65.ld"
Resolved forward reference SYSCALLS to (byte[]) SYSCALLS
Identified constant variable (byte*) BGCOL
Culled Empty Block (label) main::@4
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@5
Culled Empty Block (label) main::@6
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) BGCOL#0 ← ((byte*)) (number) $d021
to:@1
main: scope:[main] from @1
to:main::@1
main::@1: scope:[main] from main main::@2
if(true) goto main::@2
to:main::@return
main::@2: scope:[main] from main::@1
*((byte*) BGCOL#0) ← *((byte[]) SYSCALLS#0 + (number) 0)
*((byte*) BGCOL#0) ← ++ *((byte*) BGCOL#0)
to:main::@1
main::@return: scope:[main] from main::@1
return
to:@return
@1: scope:[] from @begin
(byte[]) SYSCALLS#0 ← kickasm {{ jmp main
nop
}}
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte[]) SYSCALLS
(byte[]) SYSCALLS#0
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@return
Adding number conversion cast (unumber) 0 in *((byte*) BGCOL#0) ← *((byte[]) SYSCALLS#0 + (number) 0)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53281
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Constant (const byte*) BGCOL#0 = (byte*) 53281
Constant (const byte[]) SYSCALLS#0 = kickasm {{ jmp main
nop
}}
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [1] if(true) goto main::@2
Successful SSA optimization Pass2ConstantIfs
Simplifying expression containing zero SYSCALLS#0 in [2] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0 + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused block main::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
CALL GRAPH
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2
Culled Empty Block (label) main::@1
Renumbering block main::@2 to main::@1
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0)
[6] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0)
to:main::@1
VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte[]) SYSCALLS
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
Target platform is custom
// File Comments
// Example showing how to perform linking using a linker-file
// The linker file is created using KickAssembler segments.
// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
// Upstart
.file [name="xmega65.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
// Global Constants & labels
.label BGCOL = $d021
// @begin
bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
// @1
b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
// @end
bend:
.segment Code
// main
main: {
jmp b1
// main::@1
b1:
// [5] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0) -- _deref_pbuc1=_deref_pbuc2
lda SYSCALLS
sta BGCOL
// [6] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BGCOL
jmp b1
}
// File Data
.segment Syscall
SYSCALLS:
jmp main
nop
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [5] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0) [ ] ( main:2 [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 212 combination
Uplifting [] best 212 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Example showing how to perform linking using a linker-file
// The linker file is created using KickAssembler segments.
// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
// Upstart
.file [name="xmega65.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
// Global Constants & labels
.label BGCOL = $d021
// @begin
bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
// @1
b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
// @end
bend:
.segment Code
// main
main: {
jmp b1
// main::@1
b1:
// [5] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0) -- _deref_pbuc1=_deref_pbuc2
lda SYSCALLS
sta BGCOL
// [6] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BGCOL
jmp b1
}
// File Data
.segment Syscall
SYSCALLS:
jmp main
nop
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bbegin:
Removing instruction bend:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
(byte[]) SYSCALLS
(const byte[]) SYSCALLS#0 SYSCALLS = kickasm {{ jmp main
nop
}}
(void()) main()
(label) main::@1
FINAL ASSEMBLER
Score: 170
// File Comments
// Example showing how to perform linking using a linker-file
// The linker file is created using KickAssembler segments.
// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
// Upstart
.file [name="xmega65.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
// Global Constants & labels
.label BGCOL = $d021
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
.segment Code
// main
main: {
// main::@1
b1:
// *BGCOL = SYSCALLS[0]
// [5] *((const byte*) BGCOL#0) ← *((const byte[]) SYSCALLS#0) -- _deref_pbuc1=_deref_pbuc2
lda SYSCALLS
sta BGCOL
// (*BGCOL)++;
// [6] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BGCOL
jmp b1
}
// File Data
.segment Syscall
SYSCALLS:
jmp main
nop

View File

@ -0,0 +1,12 @@
(label) @1
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
(byte[]) SYSCALLS
(const byte[]) SYSCALLS#0 SYSCALLS = kickasm {{ jmp main
nop
}}
(void()) main()
(label) main::@1

View File

@ -3,17 +3,65 @@
// See the KickAssembler manual for description of the format http://theweb.dk/KickAssembler/
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
.file [name="linking.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
.file [name="linking.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, CodeHigh, DataHigh"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef CodeHigh [start=$4000]
.segmentdef DataHigh [startAfter="CodeHigh"]
.segment Basic
:BasicUpstart(main)
.label BGCOL = $d021
.label SCREEN = $400
.segment Code
main: {
ldx #0
b1:
txa
sta base,x
inx
cpx #0
bne b1
b2:
lda BGCOL
sta.z fillscreen.c
jsr fillscreen
inc BGCOL
jmp b1
jmp b2
}
.segment CodeHigh
// fillscreen(byte zeropage(4) c)
fillscreen: {
.label c = 4
.label screen = 2
ldx #0
lda #<SCREEN
sta.z screen
lda #>SCREEN
sta.z screen+1
b2:
lda base,x
clc
adc.z c
ldy #0
sta (screen),y
inx
inc.z screen
bne !+
inc.z screen+1
!:
lda.z screen+1
cmp #>SCREEN+$3e8
bcc b2
bne !+
lda.z screen
cmp #<SCREEN+$3e8
bcc b2
!:
rts
}
.segment DataHigh
base: .fill $100, 0

View File

@ -11,5 +11,32 @@ main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0)
to:main::@1
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
[6] *((const byte[$100]) base#0 + (byte) main::i#2) ← (byte) main::i#2
[7] (byte) main::i#1 ← ++ (byte) main::i#2
[8] if((byte) main::i#1!=(byte) 0) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1 main::@3
[9] (byte) fillscreen::c#0 ← *((const byte*) BGCOL#0)
[10] call fillscreen
to:main::@3
main::@3: scope:[main] from main::@2
[11] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0)
to:main::@2
fillscreen: scope:[fillscreen] from main::@2
[12] phi()
to:fillscreen::@2
fillscreen::@2: scope:[fillscreen] from fillscreen fillscreen::@1
[13] (byte) fillscreen::i#4 ← phi( fillscreen::@1/(byte) fillscreen::i#1 fillscreen/(byte) 0 )
[13] (byte*) fillscreen::screen#4 ← phi( fillscreen::@1/(byte*) fillscreen::screen#1 fillscreen/(const byte*) SCREEN#0 )
[14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4)
[15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2
[16] (byte) fillscreen::i#1 ← ++ (byte) fillscreen::i#4
[17] (byte*) fillscreen::screen#1 ← ++ (byte*) fillscreen::screen#4
to:fillscreen::@1
fillscreen::@1: scope:[fillscreen] from fillscreen::@2
[18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2
to:fillscreen::@return
fillscreen::@return: scope:[fillscreen] from fillscreen::@1
[19] return
to:@return

View File

@ -1,72 +1,229 @@
Loading link script "xmega65.ld"
Loading link script "linking.ld"
Resolved forward reference base to (byte[$100]) base
Resolved forward reference base to (byte[$100]) base
Identified constant variable (byte*) BGCOL
Culled Empty Block (label) main::@4
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@5
Identified constant variable (byte*) SCREEN
Culled Empty Block (label) main::@2
Culled Empty Block (label) main::@6
Culled Empty Block (label) main::@5
Culled Empty Block (label) main::@7
Culled Empty Block (label) main::@8
Culled Empty Block (label) fillscreen::@4
Culled Empty Block (label) fillscreen::@3
Culled Empty Block (label) fillscreen::@5
Culled Empty Block (label) fillscreen::@6
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) BGCOL#0 ← ((byte*)) (number) $d021
to:@1
main: scope:[main] from @1
main: scope:[main] from @2
(byte) main::i#0 ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@2
if(true) goto main::@2
main::@1: scope:[main] from main main::@1
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
*((byte[$100]) base#0 + (byte) main::i#2) ← (byte) main::i#2
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$ff)
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,$ff)
if((bool~) main::$0) goto main::@1
to:main::@3
main::@3: scope:[main] from main::@1 main::@9
if(true) goto main::@4
to:main::@return
main::@2: scope:[main] from main::@1
main::@4: scope:[main] from main::@3
(byte) fillscreen::c#0 ← *((byte*) BGCOL#0)
call fillscreen
to:main::@9
main::@9: scope:[main] from main::@4
*((byte*) BGCOL#0) ← ++ *((byte*) BGCOL#0)
to:main::@1
main::@return: scope:[main] from main::@1
to:main::@3
main::@return: scope:[main] from main::@3
return
to:@return
@1: scope:[] from @begin
call main
(byte*) SCREEN#0 ← ((byte*)) (number) $400
to:@2
fillscreen: scope:[fillscreen] from main::@4
(byte) fillscreen::c#3 ← phi( main::@4/(byte) fillscreen::c#0 )
(byte) fillscreen::i#0 ← (number) 0
(byte*) fillscreen::screen#0 ← (byte*) SCREEN#0
to:fillscreen::@1
fillscreen::@1: scope:[fillscreen] from fillscreen fillscreen::@2
(byte) fillscreen::i#3 ← phi( fillscreen/(byte) fillscreen::i#0 fillscreen::@2/(byte) fillscreen::i#1 )
(byte) fillscreen::c#2 ← phi( fillscreen/(byte) fillscreen::c#3 fillscreen::@2/(byte) fillscreen::c#1 )
(byte*) fillscreen::screen#2 ← phi( fillscreen/(byte*) fillscreen::screen#0 fillscreen::@2/(byte*) fillscreen::screen#1 )
(byte*~) fillscreen::$0 ← (byte*) SCREEN#0 + (number) $3e8
(bool~) fillscreen::$1 ← (byte*) fillscreen::screen#2 < (byte*~) fillscreen::$0
if((bool~) fillscreen::$1) goto fillscreen::@2
to:fillscreen::@return
fillscreen::@2: scope:[fillscreen] from fillscreen::@1
(byte*) fillscreen::screen#3 ← phi( fillscreen::@1/(byte*) fillscreen::screen#2 )
(byte) fillscreen::i#2 ← phi( fillscreen::@1/(byte) fillscreen::i#3 )
(byte) fillscreen::c#1 ← phi( fillscreen::@1/(byte) fillscreen::c#2 )
(byte~) fillscreen::$2 ← (byte) fillscreen::c#1 + *((byte[$100]) base#0 + (byte) fillscreen::i#2)
*((byte*) fillscreen::screen#3) ← (byte~) fillscreen::$2
(byte) fillscreen::i#1 ← ++ (byte) fillscreen::i#2
(byte*) fillscreen::screen#1 ← ++ (byte*) fillscreen::screen#3
to:fillscreen::@1
fillscreen::@return: scope:[fillscreen] from fillscreen::@1
return
to:@return
@2: scope:[] from @1
(byte[$100]) base#0 ← { fill( $100, 0) }
call main
to:@3
@3: scope:[] from @2
to:@end
@end: scope:[] from @2
@end: scope:[] from @3
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte*) SCREEN
(byte*) SCREEN#0
(byte[$100]) base
(byte[$100]) base#0
(void()) fillscreen((byte) fillscreen::c)
(byte*~) fillscreen::$0
(bool~) fillscreen::$1
(byte~) fillscreen::$2
(label) fillscreen::@1
(label) fillscreen::@2
(label) fillscreen::@return
(byte) fillscreen::c
(byte) fillscreen::c#0
(byte) fillscreen::c#1
(byte) fillscreen::c#2
(byte) fillscreen::c#3
(byte) fillscreen::i
(byte) fillscreen::i#0
(byte) fillscreen::i#1
(byte) fillscreen::i#2
(byte) fillscreen::i#3
(byte*) fillscreen::screen
(byte*) fillscreen::screen#0
(byte*) fillscreen::screen#1
(byte*) fillscreen::screen#2
(byte*) fillscreen::screen#3
(void()) main()
(bool~) main::$0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@9
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
Adding number conversion cast (unumber) 0 in (byte) fillscreen::i#0 ← (number) 0
Adding number conversion cast (unumber) $3e8 in (byte*~) fillscreen::$0 ← (byte*) SCREEN#0 + (number) $3e8
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021
Inlining cast (byte*) SCREEN#0 ← (byte*)(number) $400
Inlining cast (byte) fillscreen::i#0 ← (unumber)(number) 0
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53281
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast $3e8
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (word) $3e8
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) fillscreen::c#1 = (byte) fillscreen::c#2
Alias (byte) fillscreen::i#2 = (byte) fillscreen::i#3
Alias (byte*) fillscreen::screen#2 = (byte*) fillscreen::screen#3
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) fillscreen::c#3 (byte) fillscreen::c#0
Identical Phi Values (byte) fillscreen::c#1 (byte) fillscreen::c#3
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) main::$0 [6] if((byte) main::i#1!=rangelast(0,$ff)) goto main::@1
Simple Condition (bool~) fillscreen::$1 [19] if((byte*) fillscreen::screen#2<(byte*~) fillscreen::$0) goto fillscreen::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant right-side identified [26] (byte[$100]) base#0 ← { fill( $100, 0) }
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) BGCOL#0 = (byte*) 53281
Constant (const byte) main::i#0 = 0
Constant (const byte*) SCREEN#0 = (byte*) 1024
Constant (const byte) fillscreen::i#0 = 0
Constant (const byte[$100]) base#0 = { fill( $100, 0) }
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [1] if(true) goto main::@2
Constant (const byte*) fillscreen::screen#0 = SCREEN#0
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [7] if(true) goto main::@4
Successful SSA optimization Pass2ConstantIfs
Resolved ranged next value [4] main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value [6] if(main::i#1!=rangelast(0,$ff)) goto main::@1 to (number) 0
Removing unused block main::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
Adding number conversion cast (unumber) 0 in if((byte) main::i#1!=(number) 0) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Constant right-side identified [8] (byte*~) fillscreen::$0 ← (const byte*) SCREEN#0 + (word) $3e8
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) fillscreen::$0 = SCREEN#0+$3e8
Successful SSA optimization Pass2ConstantIdentification
Successful SSA optimization Pass2LoopHeadConstantIdentification
Alias (byte*) fillscreen::screen#1 = (byte*) fillscreen::screen#2
Alias (byte) fillscreen::i#1 = (byte) fillscreen::i#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte*) fillscreen::screen#5 (const byte*) fillscreen::screen#0
Identical Phi Values (byte) fillscreen::i#5 (const byte) fillscreen::i#0
Successful SSA optimization Pass2IdenticalPhiElimination
if() condition always true - replacing block destination [18] if((const byte*) fillscreen::screen#0<(const byte*) fillscreen::$0) goto fillscreen::@2
Successful SSA optimization Pass2ConstantIfs
Inlining constant with var siblings (const byte) main::i#0
Inlining constant with var siblings (const byte) fillscreen::i#0
Inlining constant with var siblings (const byte*) fillscreen::screen#0
Constant inlined fillscreen::i#0 = (byte) 0
Constant inlined main::i#0 = (byte) 0
Constant inlined fillscreen::screen#0 = (const byte*) SCREEN#0
Constant inlined fillscreen::$0 = (const byte*) SCREEN#0+(word) $3e8
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@10(between main::@1 and main::@1)
Added new block during phi lifting fillscreen::@7(between fillscreen::@1 and fillscreen::@2)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@3
Adding NOP phi() at start of fillscreen
Adding NOP phi() at start of fillscreen::@1_1
CALL GRAPH
Calls in [] to main:2
Calls in [] to main:3
Calls in [main] to fillscreen:13
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2
Culled Empty Block (label) main::@1
Renumbering block main::@2 to main::@1
Created 3 initial phi equivalence classes
Coalesced [15] main::i#3 ← main::i#1
Coalesced [25] fillscreen::screen#6 ← fillscreen::screen#1
Coalesced [26] fillscreen::i#6 ← fillscreen::i#1
Coalesced down to 3 phi equivalence classes
Culled Empty Block (label) @1
Culled Empty Block (label) @3
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@10
Culled Empty Block (label) fillscreen::@1_1
Culled Empty Block (label) fillscreen::@7
Renumbering block @2 to @1
Renumbering block main::@4 to main::@2
Renumbering block main::@9 to main::@3
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of fillscreen
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
@ -82,16 +239,73 @@ main: scope:[main] from @1
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@1
[5] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0)
to:main::@1
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
[6] *((const byte[$100]) base#0 + (byte) main::i#2) ← (byte) main::i#2
[7] (byte) main::i#1 ← ++ (byte) main::i#2
[8] if((byte) main::i#1!=(byte) 0) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1 main::@3
[9] (byte) fillscreen::c#0 ← *((const byte*) BGCOL#0)
[10] call fillscreen
to:main::@3
main::@3: scope:[main] from main::@2
[11] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0)
to:main::@2
fillscreen: scope:[fillscreen] from main::@2
[12] phi()
to:fillscreen::@2
fillscreen::@2: scope:[fillscreen] from fillscreen fillscreen::@1
[13] (byte) fillscreen::i#4 ← phi( fillscreen::@1/(byte) fillscreen::i#1 fillscreen/(byte) 0 )
[13] (byte*) fillscreen::screen#4 ← phi( fillscreen::@1/(byte*) fillscreen::screen#1 fillscreen/(const byte*) SCREEN#0 )
[14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4)
[15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2
[16] (byte) fillscreen::i#1 ← ++ (byte) fillscreen::i#4
[17] (byte*) fillscreen::screen#1 ← ++ (byte*) fillscreen::screen#4
to:fillscreen::@1
fillscreen::@1: scope:[fillscreen] from fillscreen::@2
[18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2
to:fillscreen::@return
fillscreen::@return: scope:[fillscreen] from fillscreen::@1
[19] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte*) SCREEN
(byte[$100]) base
(void()) fillscreen((byte) fillscreen::c)
(byte~) fillscreen::$2 202.0
(byte) fillscreen::c
(byte) fillscreen::c#0 14.0
(byte) fillscreen::i
(byte) fillscreen::i#1 67.33333333333333
(byte) fillscreen::i#4 101.0
(byte*) fillscreen::screen
(byte*) fillscreen::screen#1 151.5
(byte*) fillscreen::screen#4 75.75
(void()) main()
(byte) main::i
(byte) main::i#1 16.5
(byte) main::i#2 22.0
Initial phi equivalence classes
[ main::i#2 main::i#1 ]
[ fillscreen::screen#4 fillscreen::screen#1 ]
[ fillscreen::i#4 fillscreen::i#1 ]
Added variable fillscreen::c#0 to zero page equivalence class [ fillscreen::c#0 ]
Added variable fillscreen::$2 to zero page equivalence class [ fillscreen::$2 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ fillscreen::screen#4 fillscreen::screen#1 ]
[ fillscreen::i#4 fillscreen::i#1 ]
[ fillscreen::c#0 ]
[ fillscreen::$2 ]
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Allocated zp ZP_WORD:3 [ fillscreen::screen#4 fillscreen::screen#1 ]
Allocated zp ZP_BYTE:5 [ fillscreen::i#4 fillscreen::i#1 ]
Allocated zp ZP_BYTE:6 [ fillscreen::c#0 ]
Allocated zp ZP_BYTE:7 [ fillscreen::$2 ]
INITIAL ASM
Target platform is custom
@ -102,15 +316,20 @@ Target platform is custom
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
// Upstart
.file [name="linking.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
.file [name="linking.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, CodeHigh, DataHigh"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef CodeHigh [start=$4000]
.segmentdef DataHigh [startAfter="CodeHigh"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label BGCOL = $d021
.label SCREEN = $400
// @begin
bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -130,23 +349,140 @@ bend:
.segment Code
// main
main: {
.label i = 2
// [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta.z i
jmp b1
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
jmp b1
// main::@1
b1:
// [5] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
// [6] *((const byte[$100]) base#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz1
ldy.z i
tya
sta base,y
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc.z i
// [8] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuz1_neq_0_then_la1
lda.z i
cmp #0
bne b1_from_b1
jmp b2
// main::@2
b2:
// [9] (byte) fillscreen::c#0 ← *((const byte*) BGCOL#0) -- vbuz1=_deref_pbuc1
lda BGCOL
sta.z fillscreen.c
// [10] call fillscreen
// [12] phi from main::@2 to fillscreen [phi:main::@2->fillscreen]
fillscreen_from_b2:
jsr fillscreen
jmp b3
// main::@3
b3:
// [11] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BGCOL
jmp b2
}
.segment CodeHigh
// fillscreen
// fillscreen(byte zeropage(6) c)
fillscreen: {
.label _2 = 7
.label c = 6
.label i = 5
.label screen = 3
// [13] phi from fillscreen to fillscreen::@2 [phi:fillscreen->fillscreen::@2]
b2_from_fillscreen:
// [13] phi (byte) fillscreen::i#4 = (byte) 0 [phi:fillscreen->fillscreen::@2#0] -- vbuz1=vbuc1
lda #0
sta.z i
// [13] phi (byte*) fillscreen::screen#4 = (const byte*) SCREEN#0 [phi:fillscreen->fillscreen::@2#1] -- pbuz1=pbuc1
lda #<SCREEN
sta.z screen
lda #>SCREEN
sta.z screen+1
jmp b2
// [13] phi from fillscreen::@1 to fillscreen::@2 [phi:fillscreen::@1->fillscreen::@2]
b2_from_b1:
// [13] phi (byte) fillscreen::i#4 = (byte) fillscreen::i#1 [phi:fillscreen::@1->fillscreen::@2#0] -- register_copy
// [13] phi (byte*) fillscreen::screen#4 = (byte*) fillscreen::screen#1 [phi:fillscreen::@1->fillscreen::@2#1] -- register_copy
jmp b2
// fillscreen::@2
b2:
// [14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4) -- vbuz1=vbuz2_plus_pbuc1_derefidx_vbuz3
lda.z c
ldy.z i
clc
adc base,y
sta.z _2
// [15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2 -- _deref_pbuz1=vbuz2
lda.z _2
ldy #0
sta (screen),y
// [16] (byte) fillscreen::i#1 ← ++ (byte) fillscreen::i#4 -- vbuz1=_inc_vbuz1
inc.z i
// [17] (byte*) fillscreen::screen#1 ← ++ (byte*) fillscreen::screen#4 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
jmp b1
// fillscreen::@1
b1:
// [18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2 -- pbuz1_lt_pbuc1_then_la1
lda.z screen+1
cmp #>SCREEN+$3e8
bcc b2_from_b1
bne !+
lda.z screen
cmp #<SCREEN+$3e8
bcc b2_from_b1
!:
jmp breturn
// fillscreen::@return
breturn:
// [19] return
rts
}
// File Data
.segment DataHigh
base: .fill $100, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4) [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 fillscreen::$2 ] ( main:2::fillscreen:10 [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 fillscreen::$2 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ fillscreen::c#0 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ fillscreen::i#4 fillscreen::i#1 ]
Statement [15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2 [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 ] ( main:2::fillscreen:10 [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 ] ) always clobbers reg byte y
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:6 [ fillscreen::c#0 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:5 [ fillscreen::i#4 fillscreen::i#1 ]
Statement [18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2 [ fillscreen::c#0 fillscreen::screen#1 fillscreen::i#1 ] ( main:2::fillscreen:10 [ fillscreen::c#0 fillscreen::screen#1 fillscreen::i#1 ] ) always clobbers reg byte a
Statement [14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4) [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 fillscreen::$2 ] ( main:2::fillscreen:10 [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 fillscreen::$2 ] ) always clobbers reg byte a
Statement [15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2 [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 ] ( main:2::fillscreen:10 [ fillscreen::c#0 fillscreen::screen#4 fillscreen::i#4 ] ) always clobbers reg byte y
Statement [18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2 [ fillscreen::c#0 fillscreen::screen#1 fillscreen::i#1 ] ( main:2::fillscreen:10 [ fillscreen::c#0 fillscreen::screen#1 fillscreen::i#1 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_WORD:3 [ fillscreen::screen#4 fillscreen::screen#1 ] : zp ZP_WORD:3 ,
Potential registers zp ZP_BYTE:5 [ fillscreen::i#4 fillscreen::i#1 ] : zp ZP_BYTE:5 , reg byte x ,
Potential registers zp ZP_BYTE:6 [ fillscreen::c#0 ] : zp ZP_BYTE:6 , reg byte x ,
Potential registers zp ZP_BYTE:7 [ fillscreen::$2 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [fillscreen] 227.25: zp ZP_WORD:3 [ fillscreen::screen#4 fillscreen::screen#1 ] 202: zp ZP_BYTE:7 [ fillscreen::$2 ] 168.33: zp ZP_BYTE:5 [ fillscreen::i#4 fillscreen::i#1 ] 14: zp ZP_BYTE:6 [ fillscreen::c#0 ]
Uplift Scope [main] 38.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Uplift Scope []
Uplifting [main] best 132 combination
Uplifting [] best 132 combination
Uplifting [fillscreen] best 7902 combination zp ZP_WORD:3 [ fillscreen::screen#4 fillscreen::screen#1 ] reg byte a [ fillscreen::$2 ] reg byte x [ fillscreen::i#4 fillscreen::i#1 ] zp ZP_BYTE:6 [ fillscreen::c#0 ]
Uplifting [main] best 7782 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [] best 7782 combination
Attempting to uplift remaining variables inzp ZP_BYTE:6 [ fillscreen::c#0 ]
Uplifting [fillscreen] best 7782 combination zp ZP_BYTE:6 [ fillscreen::c#0 ]
Allocated (was zp ZP_WORD:3) zp ZP_WORD:2 [ fillscreen::screen#4 fillscreen::screen#1 ]
Allocated (was zp ZP_BYTE:6) zp ZP_BYTE:4 [ fillscreen::c#0 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -156,15 +492,20 @@ ASSEMBLER BEFORE OPTIMIZATION
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
// Upstart
.file [name="linking.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
.file [name="linking.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, CodeHigh, DataHigh"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef CodeHigh [start=$4000]
.segmentdef DataHigh [startAfter="CodeHigh"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label BGCOL = $d021
.label SCREEN = $400
// @begin
bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -184,30 +525,135 @@ bend:
.segment Code
// main
main: {
// [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp b1
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
jmp b1
// main::@1
b1:
// [5] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
// [6] *((const byte[$100]) base#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx
txa
sta base,x
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
inx
// [8] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuxx_neq_0_then_la1
cpx #0
bne b1_from_b1
jmp b2
// main::@2
b2:
// [9] (byte) fillscreen::c#0 ← *((const byte*) BGCOL#0) -- vbuz1=_deref_pbuc1
lda BGCOL
sta.z fillscreen.c
// [10] call fillscreen
// [12] phi from main::@2 to fillscreen [phi:main::@2->fillscreen]
fillscreen_from_b2:
jsr fillscreen
jmp b3
// main::@3
b3:
// [11] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BGCOL
jmp b2
}
.segment CodeHigh
// fillscreen
// fillscreen(byte zeropage(4) c)
fillscreen: {
.label c = 4
.label screen = 2
// [13] phi from fillscreen to fillscreen::@2 [phi:fillscreen->fillscreen::@2]
b2_from_fillscreen:
// [13] phi (byte) fillscreen::i#4 = (byte) 0 [phi:fillscreen->fillscreen::@2#0] -- vbuxx=vbuc1
ldx #0
// [13] phi (byte*) fillscreen::screen#4 = (const byte*) SCREEN#0 [phi:fillscreen->fillscreen::@2#1] -- pbuz1=pbuc1
lda #<SCREEN
sta.z screen
lda #>SCREEN
sta.z screen+1
jmp b2
// [13] phi from fillscreen::@1 to fillscreen::@2 [phi:fillscreen::@1->fillscreen::@2]
b2_from_b1:
// [13] phi (byte) fillscreen::i#4 = (byte) fillscreen::i#1 [phi:fillscreen::@1->fillscreen::@2#0] -- register_copy
// [13] phi (byte*) fillscreen::screen#4 = (byte*) fillscreen::screen#1 [phi:fillscreen::@1->fillscreen::@2#1] -- register_copy
jmp b2
// fillscreen::@2
b2:
// [14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4) -- vbuaa=vbuz1_plus_pbuc1_derefidx_vbuxx
lda base,x
clc
adc.z c
// [15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2 -- _deref_pbuz1=vbuaa
ldy #0
sta (screen),y
// [16] (byte) fillscreen::i#1 ← ++ (byte) fillscreen::i#4 -- vbuxx=_inc_vbuxx
inx
// [17] (byte*) fillscreen::screen#1 ← ++ (byte*) fillscreen::screen#4 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
jmp b1
// fillscreen::@1
b1:
// [18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2 -- pbuz1_lt_pbuc1_then_la1
lda.z screen+1
cmp #>SCREEN+$3e8
bcc b2_from_b1
bne !+
lda.z screen
cmp #<SCREEN+$3e8
bcc b2_from_b1
!:
jmp breturn
// fillscreen::@return
breturn:
// [19] return
rts
}
// File Data
.segment DataHigh
base: .fill $100, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp b3
Removing instruction jmp b2
Removing instruction jmp b1
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b1 with b1
Replacing label b2_from_b1 with b2
Replacing label b2_from_b1 with b2
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_b1:
Removing instruction b2_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bbegin:
Removing instruction bend:
Removing instruction b1_from_main:
Removing instruction fillscreen_from_b2:
Removing instruction b3:
Removing instruction b2_from_fillscreen:
Removing instruction b1:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp b1
Removing instruction jmp b2
Succesful ASM optimization Pass5NextJumpElimination
FINAL SYMBOL TABLE
(label) @1
@ -215,13 +661,40 @@ FINAL SYMBOL TABLE
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
(byte[$100]) base
(const byte[$100]) base#0 base = { fill( $100, 0) }
(void()) fillscreen((byte) fillscreen::c)
(byte~) fillscreen::$2 reg byte a 202.0
(label) fillscreen::@1
(label) fillscreen::@2
(label) fillscreen::@return
(byte) fillscreen::c
(byte) fillscreen::c#0 c zp ZP_BYTE:4 14.0
(byte) fillscreen::i
(byte) fillscreen::i#1 reg byte x 67.33333333333333
(byte) fillscreen::i#4 reg byte x 101.0
(byte*) fillscreen::screen
(byte*) fillscreen::screen#1 screen zp ZP_WORD:2 151.5
(byte*) fillscreen::screen#4 screen zp ZP_WORD:2 75.75
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(byte) main::i
(byte) main::i#1 reg byte x 16.5
(byte) main::i#2 reg byte x 22.0
reg byte x [ main::i#2 main::i#1 ]
zp ZP_WORD:2 [ fillscreen::screen#4 fillscreen::screen#1 ]
reg byte x [ fillscreen::i#4 fillscreen::i#1 ]
zp ZP_BYTE:4 [ fillscreen::c#0 ]
reg byte a [ fillscreen::$2 ]
FINAL ASSEMBLER
Score: 90
Score: 6477
// File Comments
// Example showing how to perform linking using a linker-file
@ -230,15 +703,20 @@ Score: 90
// Specifying the linker script file is done using the #pragma link(<file>)
// It can also be specified using kickc command line option -T <file>
// Upstart
.file [name="linking.bin", type="bin", segments="XMega65Bin"]
.segmentdef XMega65Bin [segments="Syscall, Code, Data, Stack, Zeropage"]
.segmentdef Syscall [start=$8000, max=$81ff]
.segmentdef Code [start=$8200, min=$8200, max=$bdff]
.segmentdef Data [startAfter="Code", min=$8200, max=$bdff]
.segmentdef Stack [min=$be00, max=$beff, fill]
.segmentdef Zeropage [min=$bf00, max=$bfff, fill]
.file [name="linking.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data, CodeHigh, DataHigh"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef CodeHigh [start=$4000]
.segmentdef DataHigh [startAfter="CodeHigh"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label BGCOL = $d021
.label SCREEN = $400
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
@ -249,12 +727,91 @@ Score: 90
.segment Code
// main
main: {
// [5] phi from main to main::@1 [phi:main->main::@1]
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
// main::@1
b1:
// base[i] = i
// [6] *((const byte[$100]) base#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx
txa
sta base,x
// for(char i:0..255)
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
inx
// [8] if((byte) main::i#1!=(byte) 0) goto main::@1 -- vbuxx_neq_0_then_la1
cpx #0
bne b1
// main::@2
b2:
// fillscreen(*BGCOL)
// [9] (byte) fillscreen::c#0 ← *((const byte*) BGCOL#0) -- vbuz1=_deref_pbuc1
lda BGCOL
sta.z fillscreen.c
// [10] call fillscreen
// [12] phi from main::@2 to fillscreen [phi:main::@2->fillscreen]
jsr fillscreen
// main::@3
// (*BGCOL)++;
// [5] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
// [11] *((const byte*) BGCOL#0) ← ++ *((const byte*) BGCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BGCOL
jmp b1
jmp b2
}
.segment CodeHigh
// fillscreen
// fillscreen(byte zeropage(4) c)
fillscreen: {
.label c = 4
.label screen = 2
// [13] phi from fillscreen to fillscreen::@2 [phi:fillscreen->fillscreen::@2]
// [13] phi (byte) fillscreen::i#4 = (byte) 0 [phi:fillscreen->fillscreen::@2#0] -- vbuxx=vbuc1
ldx #0
// [13] phi (byte*) fillscreen::screen#4 = (const byte*) SCREEN#0 [phi:fillscreen->fillscreen::@2#1] -- pbuz1=pbuc1
lda #<SCREEN
sta.z screen
lda #>SCREEN
sta.z screen+1
// [13] phi from fillscreen::@1 to fillscreen::@2 [phi:fillscreen::@1->fillscreen::@2]
// [13] phi (byte) fillscreen::i#4 = (byte) fillscreen::i#1 [phi:fillscreen::@1->fillscreen::@2#0] -- register_copy
// [13] phi (byte*) fillscreen::screen#4 = (byte*) fillscreen::screen#1 [phi:fillscreen::@1->fillscreen::@2#1] -- register_copy
// fillscreen::@2
b2:
// c+base[i++]
// [14] (byte~) fillscreen::$2 ← (byte) fillscreen::c#0 + *((const byte[$100]) base#0 + (byte) fillscreen::i#4) -- vbuaa=vbuz1_plus_pbuc1_derefidx_vbuxx
lda base,x
clc
adc.z c
// *screen = c+base[i++]
// [15] *((byte*) fillscreen::screen#4) ← (byte~) fillscreen::$2 -- _deref_pbuz1=vbuaa
ldy #0
sta (screen),y
// *screen = c+base[i++];
// [16] (byte) fillscreen::i#1 ← ++ (byte) fillscreen::i#4 -- vbuxx=_inc_vbuxx
inx
// for( char *screen = SCREEN; screen<SCREEN+1000; screen++)
// [17] (byte*) fillscreen::screen#1 ← ++ (byte*) fillscreen::screen#4 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// fillscreen::@1
// [18] if((byte*) fillscreen::screen#1<(const byte*) SCREEN#0+(word) $3e8) goto fillscreen::@2 -- pbuz1_lt_pbuc1_then_la1
lda.z screen+1
cmp #>SCREEN+$3e8
bcc b2
bne !+
lda.z screen
cmp #<SCREEN+$3e8
bcc b2
!:
// fillscreen::@return
// }
// [19] return
rts
}
// File Data
.segment DataHigh
base: .fill $100, 0

View File

@ -3,6 +3,33 @@
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
(byte[$100]) base
(const byte[$100]) base#0 base = { fill( $100, 0) }
(void()) fillscreen((byte) fillscreen::c)
(byte~) fillscreen::$2 reg byte a 202.0
(label) fillscreen::@1
(label) fillscreen::@2
(label) fillscreen::@return
(byte) fillscreen::c
(byte) fillscreen::c#0 c zp ZP_BYTE:4 14.0
(byte) fillscreen::i
(byte) fillscreen::i#1 reg byte x 67.33333333333333
(byte) fillscreen::i#4 reg byte x 101.0
(byte*) fillscreen::screen
(byte*) fillscreen::screen#1 screen zp ZP_WORD:2 151.5
(byte*) fillscreen::screen#4 screen zp ZP_WORD:2 75.75
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(byte) main::i
(byte) main::i#1 reg byte x 16.5
(byte) main::i#2 reg byte x 22.0
reg byte x [ main::i#2 main::i#1 ]
zp ZP_WORD:2 [ fillscreen::screen#4 fillscreen::screen#1 ]
reg byte x [ fillscreen::i#4 fillscreen::i#1 ]
zp ZP_BYTE:4 [ fillscreen::c#0 ]
reg byte a [ fillscreen::$2 ]