mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-16 18:30:37 +00:00
Fixed typedef arrays (still no array of array). Closes #376
This commit is contained in:
parent
5a8654b0e7
commit
e3b54f34d7
@ -107,7 +107,7 @@ public class VariableBuilder {
|
||||
* @return true if the variable is in the global scope
|
||||
*/
|
||||
public boolean isScopeGlobal() {
|
||||
return ScopeRef.ROOT.equals(scope.getRef());
|
||||
return ScopeRef.ROOT.equals(scope.getRef()) || ScopeRef.TYPEDEFS.equals(scope.getRef());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.LiveRangeEquivalenceClassSet;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeProgram;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
|
||||
/** The program scope containing the symbols of a program */
|
||||
public class ProgramScope extends Scope {
|
||||
@ -40,7 +41,8 @@ public class ProgramScope extends Scope {
|
||||
return "program";
|
||||
}
|
||||
|
||||
private TypeDefsScope typeDefsScope = new TypeDefsScope("typedefs", this);
|
||||
/** The scope holding typedefs. */
|
||||
private TypeDefsScope typeDefsScope = new TypeDefsScope(ScopeRef.TYPEDEFS.getFullName(), this);
|
||||
|
||||
public Scope getTypeDefScope() {
|
||||
return typeDefsScope;
|
||||
|
@ -8,6 +8,9 @@ public class ScopeRef extends SymbolRef {
|
||||
/** The ROOT scope of the program. */
|
||||
public static final ScopeRef ROOT = new ScopeRef("");
|
||||
|
||||
/** The scope holding type definitions. */
|
||||
public static final ScopeRef TYPEDEFS = new ScopeRef("typedefs");
|
||||
|
||||
public ScopeRef(String fullName) {
|
||||
super(fullName);
|
||||
}
|
||||
|
@ -1769,17 +1769,15 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
@Override
|
||||
public Object visitTypeNamedRef(KickCParser.TypeNamedRefContext ctx) {
|
||||
|
||||
Scope typeDefScope = program.getScope().getTypeDefScope();
|
||||
Variable typeDefVariable = typeDefScope.getVariable(ctx.getText());
|
||||
Variable typeDefVariable = typeDefScope.getVar(ctx.getText());
|
||||
if(typeDefVariable != null) {
|
||||
varDecl.setDeclType(typeDefVariable.getType());
|
||||
if(typeDefVariable.getArraySpec() != null)
|
||||
// TODO: Handle typedef array of array correctly
|
||||
throw new InternalError("Typedef with arrays not supported!");
|
||||
varDecl.getDeclType().setArraySpec(typeDefVariable.getArraySpec());
|
||||
if(typeDefVariable.isNoModify() || typeDefVariable.isVolatile() || typeDefVariable.isToNoModify() || typeDefVariable.isToVolatile())
|
||||
// TODO: Handle type directives correctly
|
||||
throw new InternalError("Typedef with type directives not supported!");
|
||||
varDecl.setDeclType(typeDefVariable.getType());
|
||||
return null;
|
||||
}
|
||||
throw new CompileError("Unknown type " + ctx.getText(), new StatementSource(ctx));
|
||||
@ -1851,9 +1849,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
this.visit(declArrayContext);
|
||||
}
|
||||
String typedefName = ctx.NAME().getText();
|
||||
final Variable typeDefVar = Variable.createPhiMaster(typedefName, varDecl.getEffectiveType(), typedefScope, defaultMemoryArea, currentDataSegment);
|
||||
typeDefVar.setArraySpec(varDecl.getEffectiveArraySpec());
|
||||
typedefScope.add(typeDefVar);
|
||||
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, variableBuilderConfig);
|
||||
final Variable typeDefVar = varBuilder.build();
|
||||
scopeStack.pop();
|
||||
varDecl.exitType();
|
||||
return null;
|
||||
|
@ -942,10 +942,25 @@ public class TestPrograms {
|
||||
}
|
||||
|
||||
//@Test
|
||||
//public void testTypedef3() throws IOException, URISyntaxException {
|
||||
// compileAndCompare("typedef-3");
|
||||
//public void testPointerConstTypedef() throws IOException, URISyntaxException {
|
||||
// compileAndCompare("pointer-const-typedef");
|
||||
//}
|
||||
|
||||
//@Test
|
||||
//public void testTypedef5() throws IOException, URISyntaxException {
|
||||
// compileAndCompare("typedef-5");
|
||||
//}
|
||||
|
||||
//@Test
|
||||
//public void testTypedef4() throws IOException, URISyntaxException {
|
||||
// compileAndCompare("typedef-4");
|
||||
//}
|
||||
|
||||
@Test
|
||||
public void testTypedef3() throws IOException, URISyntaxException {
|
||||
compileAndCompare("typedef-3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypedef2() throws IOException, URISyntaxException {
|
||||
compileAndCompare("typedef-2");
|
||||
@ -1781,10 +1796,6 @@ public class TestPrograms {
|
||||
assertError("pointer-const-deep", "Deep const/volatile not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointerConstTypedef() throws IOException, URISyntaxException {
|
||||
compileAndCompare("pointer-const-typedef");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointerConst() throws IOException, URISyntaxException {
|
||||
|
12
src/test/kc/typedef-4.kc
Normal file
12
src/test/kc/typedef-4.kc
Normal file
@ -0,0 +1,12 @@
|
||||
// Typedef a const type
|
||||
|
||||
char* const SCREEN = 0x0400;
|
||||
|
||||
typedef const char C;
|
||||
|
||||
C c = 'c';
|
||||
|
||||
void main() {
|
||||
SCREEN[0] = c++;
|
||||
SCREEN[1] = c++;
|
||||
}
|
11
src/test/kc/typedef-5.kc
Normal file
11
src/test/kc/typedef-5.kc
Normal file
@ -0,0 +1,11 @@
|
||||
// Typedef a const type and instantiate a pointer to it
|
||||
|
||||
char* const SCREEN = 0x0400;
|
||||
|
||||
typedef const char C;
|
||||
|
||||
C * cp = 0xa003;
|
||||
|
||||
void main() {
|
||||
SCREEN[0] = *cp;
|
||||
}
|
@ -14,7 +14,7 @@ main: scope:[main] from @1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2)
|
||||
[6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2)
|
||||
[7] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[8] if((byte) main::i#1!=(byte) 7) goto main::@1
|
||||
to:main::@return
|
||||
|
@ -10,7 +10,7 @@ main: scope:[main] from @1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
*((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2)
|
||||
*((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2)
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,6)
|
||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,6)
|
||||
if((bool~) main::$0) goto main::@1
|
||||
@ -30,7 +30,7 @@ SYMBOL TABLE SSA
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte*) SCREEN = (byte*)(number) $400
|
||||
(const nomodify byte*) SCREEN = (byte*)(number) $400
|
||||
(const byte*) a[(number) 7] = (byte*) "cml"
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
@ -94,7 +94,7 @@ main: scope:[main] from @1
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2)
|
||||
[6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2)
|
||||
[7] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[8] if((byte) main::i#1!=(byte) 7) goto main::@1
|
||||
to:main::@return
|
||||
@ -156,7 +156,7 @@ main: {
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz1
|
||||
// [6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz1
|
||||
ldy.z i
|
||||
lda a,y
|
||||
sta SCREEN,y
|
||||
@ -178,9 +178,9 @@ main: {
|
||||
.fill 3, 0
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||
Statement [6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||
Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||
Statement [6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] { } ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
@ -228,7 +228,7 @@ main: {
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
|
||||
// [6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
|
||||
lda a,x
|
||||
sta SCREEN,x
|
||||
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||
@ -276,7 +276,7 @@ FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||
(const byte*) a[(number) 7] = (byte*) "cml"
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
@ -316,7 +316,7 @@ main: {
|
||||
// main::@1
|
||||
__b1:
|
||||
// SCREEN[i] = a[i]
|
||||
// [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
|
||||
// [6] *((const nomodify byte*) SCREEN + (byte) main::i#2) ← *((const byte*) a + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
|
||||
lda a,x
|
||||
sta SCREEN,x
|
||||
// for(char i:0..6)
|
||||
|
@ -1,7 +1,7 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||
(const byte*) a[(number) 7] = (byte*) "cml"
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
|
Loading…
x
Reference in New Issue
Block a user