mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-21 07:29:14 +00:00
Fixed infinite recursion
This commit is contained in:
parent
0efe62585b
commit
96f2610d25
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.fragment;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.parser.KickCLexer;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import org.antlr.v4.runtime.*;
|
||||
@ -19,6 +20,8 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class AsmFragmentManager {
|
||||
|
||||
static boolean verboseFragmentLog = false;
|
||||
|
||||
/**
|
||||
* Cache for fragment files. Maps signature to the parsed file.
|
||||
*/
|
||||
@ -26,8 +29,8 @@ public class AsmFragmentManager {
|
||||
|
||||
private static KickCParser.AsmFileContext UNKNOWN = new KickCParser.AsmFileContext(null, 0);
|
||||
|
||||
public static AsmFragment getFragment(AsmFragmentSignature signature) {
|
||||
KickCParser.AsmFileContext fragmentFile = getFragmentFile(signature.getSignature());
|
||||
public static AsmFragment getFragment(AsmFragmentSignature signature, CompileLog log) {
|
||||
KickCParser.AsmFileContext fragmentFile = getFragmentFile(signature.getSignature(), log);
|
||||
AsmFragment fragment = new AsmFragment(
|
||||
signature.getProgram(),
|
||||
signature.getSignature(),
|
||||
@ -37,14 +40,20 @@ public class AsmFragmentManager {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private static KickCParser.AsmFileContext getFragmentFile(String signature) {
|
||||
private static KickCParser.AsmFileContext getFragmentFile(String signature, CompileLog log) {
|
||||
KickCParser.AsmFileContext fragment = fragmentFileCache.get(signature);
|
||||
if (fragment == UNKNOWN) {
|
||||
if (verboseFragmentLog) {
|
||||
log.append("Unknown fragment " + signature);
|
||||
}
|
||||
throw new UnknownFragmentException(signature);
|
||||
}
|
||||
if (fragment == null) {
|
||||
CharStream fragmentCharStream = loadOrSynthesizeFragment(signature);
|
||||
CharStream fragmentCharStream = loadOrSynthesizeFragment(signature, log);
|
||||
if (fragmentCharStream == null) {
|
||||
if (verboseFragmentLog) {
|
||||
log.append("Unknown fragment " + signature);
|
||||
}
|
||||
fragmentFileCache.put(signature, UNKNOWN);
|
||||
throw new UnknownFragmentException(signature);
|
||||
}
|
||||
@ -54,10 +63,17 @@ public class AsmFragmentManager {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private static CharStream loadOrSynthesizeFragment(String signature) {
|
||||
private static CharStream loadOrSynthesizeFragment(String signature, CompileLog log) {
|
||||
CharStream fragmentCharStream = loadFragment(signature);
|
||||
if (fragmentCharStream == null) {
|
||||
fragmentCharStream = synthesizeFragment(signature);
|
||||
if (verboseFragmentLog) {
|
||||
log.append("Attempting fragment synthesis " + signature);
|
||||
}
|
||||
fragmentCharStream = synthesizeFragment(signature, log);
|
||||
} else {
|
||||
if (verboseFragmentLog) {
|
||||
log.append("Succesfully loaded fragment " + signature);
|
||||
}
|
||||
}
|
||||
return fragmentCharStream;
|
||||
}
|
||||
@ -68,7 +84,7 @@ public class AsmFragmentManager {
|
||||
* @param signature The signature of the fragment to synthesize
|
||||
* @return The synthesized fragment file contents. Null if the fragment could not be synthesized.
|
||||
*/
|
||||
private static CharStream synthesizeFragment(String signature) {
|
||||
private static CharStream synthesizeFragment(String signature, CompileLog log) {
|
||||
|
||||
Map<String, String> mapZpsby = new LinkedHashMap<>();
|
||||
mapZpsby.put("zpsby2", "zpsby1");
|
||||
@ -105,12 +121,12 @@ public class AsmFragmentManager {
|
||||
synths.add(new FragmentSynthesis("(.*)=zpby1(.*)", ".*=.*as?by.*|zpby1=.*", "lda {zpby1}\n", "$1=aby$2", null, mapZpby));
|
||||
synths.add(new FragmentSynthesis("(.*)=zpsby1(.*)", ".*=.*as?by.*|zpsby1=.*", "lda {zpsby1}\n", "$1=aby$2", null, mapZpsby));
|
||||
synths.add(new FragmentSynthesis("(.*)=_deref_cowo1(.*)", ".*=.*as?by.*", "lda {cowo1}\n", "$1=aby$2", null, mapConst));
|
||||
synths.add(new FragmentSynthesis("(.*)=_deref_zpptrby1(.*)", ".*=.*as?by.*|.*=.*ys?by.*", "ldy #0\n"+"lda ({zpptrby1}),y\n", "$1=aby$2", null, mapZpptrby));
|
||||
synths.add(new FragmentSynthesis("(.*)=_deref_zpptrby1(.*)", ".*=.*as?by.*|.*=.*ys?by.*", "ldy #0\n" + "lda ({zpptrby1}),y\n", "$1=aby$2", null, mapZpptrby));
|
||||
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_xby", ".*=[ax]s?by.*xs?by", "txa\n", "$1=$2_aby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_xsby", ".*=[ax]s?by.*xs?by", "txa\n", "$1=$2_asby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_yby", ".*=[ay]s?by.*ys?by", "tya\n", "$1=$2_aby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_ysby", ".*=[ay]s?by.*ys?by", "tya\n", "$1=$2_asby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_xby", ".*=[ax]s?by.*xs?by|.*derefidx_xs?by", "txa\n", "$1=$2_aby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_xsby", ".*=[ax]s?by.*xs?by|.*derefidx_xs?by", "txa\n", "$1=$2_asby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_yby", ".*=[ay]s?by.*ys?by|.*derefidx_ys?by", "tya\n", "$1=$2_aby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_ysby", ".*=[ay]s?by.*ys?by|.*derefidx_ys?by", "tya\n", "$1=$2_asby", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_zpby1", ".*=.*as?by.*", "lda {zpby1}\n", "$1=$2_aby", null, mapZpby));
|
||||
synths.add(new FragmentSynthesis("(.*)=(.*)_zpsby1", ".*=.*as?by.*", "lda {zpsby1}\n", "$1=$2_asby", null, mapZpsby));
|
||||
|
||||
@ -125,7 +141,7 @@ public class AsmFragmentManager {
|
||||
synths.add(new FragmentSynthesis("zpby1_(lt|gt|le|ge|eq|neq)_(.*)", ".*as?by.*", "lda {zpby1}\n", "aby_$1_$2", null, mapZpby));
|
||||
synths.add(new FragmentSynthesis("zpsby1_(lt|gt|le|ge|eq|neq)_(.*)", ".*as?by.*", "lda {zpsby1}\n", "asby_$1_$2", null, mapZpsby));
|
||||
synths.add(new FragmentSynthesis("_deref_cowo1_(lt|gt|le|ge|eq|neq)_(.*)", ".*as?by.*", "lda {cowo1}\n", "aby_$1_$2", null, mapConst));
|
||||
synths.add(new FragmentSynthesis("_deref_zpptrby1_(lt|gt|le|ge|eq|neq)_(.*)", ".*=.*as?by.*|.*=.*ys?by.*", "ldy #0\n"+"lda ({zpptrby1}),y\n", "aby_$1_$2", null, mapZpptrby));
|
||||
synths.add(new FragmentSynthesis("_deref_zpptrby1_(lt|gt|le|ge|eq|neq)_(.*)", ".*=.*as?by.*|.*=.*ys?by.*", "ldy #0\n" + "lda ({zpptrby1}),y\n", "aby_$1_$2", null, mapZpptrby));
|
||||
synths.add(new FragmentSynthesis("(.*)_ge_(as?by)_then_(.*)", ".*[a]s?by.*_ge.*", null, "$2_lt_$1_then_$3", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)_ge_(xs?by)_then_(.*)", ".*[ax]s?by.*_ge.*", null, "$2_lt_$1_then_$3", null, null));
|
||||
synths.add(new FragmentSynthesis("(.*)_ge_(ys?by)_then_(.*)", ".*[axy]s?by.*_ge.*", null, "$2_lt_$1_then_$3", null, null));
|
||||
@ -146,8 +162,11 @@ public class AsmFragmentManager {
|
||||
synths.add(new FragmentSynthesis("(.*)_eq_(ys?by)_then_(.*)", ".*[axy]s?by.*_eq.*", null, "$2_eq_$1_then_$3", null, null));
|
||||
|
||||
for (FragmentSynthesis synth : synths) {
|
||||
CharStream synthesized = synth.synthesize(signature);
|
||||
if(synthesized!=null) {
|
||||
CharStream synthesized = synth.synthesize(signature, log);
|
||||
if (synthesized != null) {
|
||||
if (verboseFragmentLog) {
|
||||
log.append("Succesfully synthesized fragment " + signature + " (from " + synth.getSubSignature() + ")");
|
||||
}
|
||||
return synthesized;
|
||||
}
|
||||
}
|
||||
@ -156,7 +175,9 @@ public class AsmFragmentManager {
|
||||
|
||||
}
|
||||
|
||||
/** AsmFragment synthesis based on matching fragment signature and reusing another fragment with added prefix/postfix and some bind-mappings*/
|
||||
/**
|
||||
* AsmFragment synthesis based on matching fragment signature and reusing another fragment with added prefix/postfix and some bind-mappings
|
||||
*/
|
||||
private static class FragmentSynthesis {
|
||||
|
||||
private String sigMatch;
|
||||
@ -165,6 +186,7 @@ public class AsmFragmentManager {
|
||||
private String sigReplace;
|
||||
private String asmPostfix;
|
||||
private Map<String, String> bindMappings;
|
||||
private String subSignature;
|
||||
|
||||
public FragmentSynthesis(String sigMatch, String sigAvoid, String asmPrefix, String sigReplace, String asmPostfix, Map<String, String> bindMappings) {
|
||||
this.sigMatch = sigMatch;
|
||||
@ -175,23 +197,23 @@ public class AsmFragmentManager {
|
||||
this.bindMappings = bindMappings;
|
||||
}
|
||||
|
||||
public CharStream synthesize(String signature) {
|
||||
if (signature.matches(sigMatch) ) {
|
||||
public CharStream synthesize(String signature, CompileLog log) {
|
||||
if (signature.matches(sigMatch)) {
|
||||
if (sigAvoid == null || !signature.matches(sigAvoid)) {
|
||||
String subSignature = regexpRewriteSignature(signature, sigMatch, sigReplace);
|
||||
if(bindMappings!=null) {
|
||||
subSignature = regexpRewriteSignature(signature, sigMatch, sigReplace);
|
||||
if (bindMappings != null) {
|
||||
for (String bound : bindMappings.keySet()) {
|
||||
subSignature = subSignature.replace(bound, bindMappings.get(bound));
|
||||
}
|
||||
}
|
||||
CharStream subCharStream = loadOrSynthesizeFragment(subSignature);
|
||||
CharStream subCharStream = loadOrSynthesizeFragment(subSignature, log);
|
||||
if (subCharStream != null) {
|
||||
StringBuilder newFragment = new StringBuilder();
|
||||
if(asmPrefix!=null) {
|
||||
if (asmPrefix != null) {
|
||||
newFragment.append(asmPrefix);
|
||||
}
|
||||
String subFragment = subCharStream.toString();
|
||||
if(bindMappings!=null) {
|
||||
if (bindMappings != null) {
|
||||
List<String> reverse = new ArrayList<>(bindMappings.keySet());
|
||||
Collections.reverse(reverse);
|
||||
for (String bound : reverse) {
|
||||
@ -199,7 +221,7 @@ public class AsmFragmentManager {
|
||||
}
|
||||
}
|
||||
newFragment.append(subFragment);
|
||||
if(asmPostfix!=null) {
|
||||
if (asmPostfix != null) {
|
||||
newFragment.append("\n");
|
||||
newFragment.append(asmPostfix);
|
||||
}
|
||||
@ -210,6 +232,9 @@ public class AsmFragmentManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getSubSignature() {
|
||||
return subSignature;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,7 +205,7 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
AsmFragmentSignature signature = new AsmFragmentSignature(assignment, assignmentAlu, program);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(signature);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(signature, program.getLog());
|
||||
asm.getCurrentSegment().setFragment(asmFragment.getName());
|
||||
asmFragment.generate(asm);
|
||||
aluState.clear();
|
||||
@ -232,14 +232,14 @@ public class Pass4CodeGeneration {
|
||||
asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue));
|
||||
} else {
|
||||
AsmFragmentSignature asmFragmentSignature = new AsmFragmentSignature(assignment, program);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmFragmentSignature);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmFragmentSignature, program.getLog());
|
||||
asm.getCurrentSegment().setFragment(asmFragment.getName());
|
||||
asmFragment.generate(asm);
|
||||
}
|
||||
}
|
||||
} else if (statement instanceof StatementConditionalJump) {
|
||||
AsmFragmentSignature asmSignature = new AsmFragmentSignature((StatementConditionalJump) statement, block, program, getGraph());
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmSignature);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmSignature, program.getLog());
|
||||
asm.getCurrentSegment().setFragment(asmFragment.getName());
|
||||
asmFragment.generate(asm);
|
||||
} else if (statement instanceof StatementCall) {
|
||||
@ -349,7 +349,7 @@ public class Pass4CodeGeneration {
|
||||
asm.getCurrentSegment().setFragment("register_copy");
|
||||
} else {
|
||||
AsmFragmentSignature asmSignature = new AsmFragmentSignature(lValue, rValue, program, scope);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmSignature);
|
||||
AsmFragment asmFragment = AsmFragmentManager.getFragment(asmSignature, program.getLog());
|
||||
asm.getCurrentSegment().setFragment(asmFragment.getName());
|
||||
asmFragment.generate(asm);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ byte* SCREEN2 = $0600;
|
||||
|
||||
void main() {
|
||||
for( byte b: 0..100) {
|
||||
byte b2 = 100-b;
|
||||
byte b2 = 100-b; // Subtract byte from byte (not signed)
|
||||
SCREEN2[b] = b2;
|
||||
signed byte sb = - (signed byte)b;
|
||||
SCREEN[b] = (byte)sb;
|
||||
|
Loading…
x
Reference in New Issue
Block a user