1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-26 15:30:28 +00:00

Removed inline kickasm parse trick that created a statement and then deleted it again.

This commit is contained in:
jespergravgaard 2020-06-23 00:22:56 +02:00
parent 3781096d01
commit f2314caadb
2 changed files with 42 additions and 27 deletions

View File

@ -441,31 +441,56 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
@Override
public Object visitDeclKasm(KickCParser.DeclKasmContext ctx) {
String kasm = ctx.KICKASM_BODY().getText();
public Object visitStmtDeclKasm(KickCParser.StmtDeclKasmContext ctx) {
final KickAsm kickAsm = (KickAsm) this.visit(ctx.declKasm());
StatementKickAsm statementKickAsm = new StatementKickAsm(kickAsm.kickAsmCode, kickAsm.bytes, kickAsm.cycles, kickAsm.uses, kickAsm.declaredClobber, StatementSource.kickAsm(ctx.declKasm()), ensureUnusedComments(getCommentsSymbol(ctx)));
addStatement(statementKickAsm);
return statementKickAsm;
}
/** Inline KickAssembler code. */
static class KickAsm {
/** KickAssembler code. */
private final String kickAsmCode;
/** Variables/constants used by the kickasm code. */
private final List<SymbolRef> uses;
/** The number of bytes generated by the kick-assembler code. */
private RValue bytes;
/** The number of cycles used by the generated kick-assembler code. */
private RValue cycles;
/** Declared clobber for the inline kick-assembler . */
private AsmClobber declaredClobber;
public KickAsm(String kickAsmCode) {
this.kickAsmCode = kickAsmCode;
this.uses = new ArrayList<>();
}
}
@Override
public KickAsm visitDeclKasm(KickCParser.DeclKasmContext ctx) {
String kasmBody = ctx.KICKASM_BODY().getText();
Pattern p = Pattern.compile("\\{\\{[\\s]*(.*)[\\s]*\\}\\}", Pattern.DOTALL);
Matcher m = p.matcher(kasm);
Matcher m = p.matcher(kasmBody);
if(m.find()) {
String kickAsmCode = m.group(1).replaceAll("\r", "");
StatementKickAsm statementKickAsm = new StatementKickAsm(kickAsmCode, StatementSource.kickAsm(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
KickAsm kickAsm = new KickAsm(kickAsmCode);
if(ctx.asmDirectives() != null) {
List<AsmDirective> asmDirectives = this.visitAsmDirectives(ctx.asmDirectives());
for(AsmDirective asmDirective : asmDirectives) {
if(asmDirective instanceof AsmDirectiveBytes) {
statementKickAsm.setBytes(((AsmDirectiveBytes) asmDirective).getBytes());
kickAsm.bytes = ((AsmDirectiveBytes) asmDirective).getBytes();
} else if(asmDirective instanceof AsmDirectiveCycles) {
statementKickAsm.setCycles(((AsmDirectiveCycles) asmDirective).getCycles());
kickAsm.cycles = ((AsmDirectiveCycles) asmDirective).getCycles();
} else if(asmDirective instanceof AsmDirectiveUses) {
statementKickAsm.addUses(((AsmDirectiveUses) asmDirective).getUses());
kickAsm.uses.add(((AsmDirectiveUses) asmDirective).getUses());
} else if(asmDirective instanceof AsmDirectiveClobber) {
statementKickAsm.setDeclaredClobber(((AsmDirectiveClobber) asmDirective).getClobber());
kickAsm.declaredClobber = ((AsmDirectiveClobber) asmDirective).getClobber();
} else {
throw new CompileError("kickasm does not support directive " + asmDirective, statementKickAsm);
throw new CompileError("kickasm does not support directive " + asmDirective, StatementSource.kickAsm(ctx));
}
}
}
addStatement(statementKickAsm);
return statementKickAsm;
return kickAsm;
}
return null;
}
@ -1003,27 +1028,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
throw new CompileError("KickAsm initializers only supported for arrays " + varDecl.getEffectiveType().getTypeName(), statementSource);
}
// Add KickAsm statement
StatementKickAsm kasm = (StatementKickAsm) this.visit(ctx.declKasm());
if(kasm.getCycles() != null) {
KickAsm kasm = (KickAsm) this.visit(ctx.declKasm());
if(kasm.cycles != null) {
throw new CompileError("KickAsm initializers does not support 'cycles' directive.", statementSource);
}
if(kasm.getBytes() != null) {
if(kasm.bytes != null) {
throw new CompileError("KickAsm initializers does not support 'bytes' directive.", statementSource);
}
if(kasm.getDeclaredClobber() != null) {
if(kasm.declaredClobber != null) {
throw new CompileError("KickAsm initializers does not support 'clobbers' directive.", statementSource);
}
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.getKickAsmCode(), kasm.getUses(), varDecl.getEffectiveArraySpec().getArraySize());
// Remove the KickAsm statement
ProcedureCompilation procedureCompilation = getCurrentProcedureCompilation();
if(procedureCompilation == null) {
// Statement outside procedure declaration - put into the _init procedure
Procedure initProc = program.getScope().getLocalProcedure(SymbolRef.INIT_PROC_NAME);
procedureCompilation = program.getProcedureCompilation(initProc.getRef());
}
final StatementSequence sequence = procedureCompilation.getStatementSequence();
sequence.getStatements().remove(sequence.getStatements().size() - 1);
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.kickAsmCode, kasm.uses, varDecl.getEffectiveArraySpec().getArraySize());
// Add a constant variable
Scope scope = getCurrentScope();
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());

View File

@ -2,7 +2,7 @@
char* const TABLE = 0x2000;
kickasm(pc TABLE) {{
char a[] = kickasm(pc TABLE) {{
.byte 1, 2, 3
}};