mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 00:29:10 +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
|
* @return true if the variable is in the global scope
|
||||||
*/
|
*/
|
||||||
public boolean isScopeGlobal() {
|
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.Program;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeProgram;
|
import dk.camelot64.kickc.model.types.SymbolTypeProgram;
|
||||||
|
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||||
|
|
||||||
/** The program scope containing the symbols of a program */
|
/** The program scope containing the symbols of a program */
|
||||||
public class ProgramScope extends Scope {
|
public class ProgramScope extends Scope {
|
||||||
@ -40,7 +41,8 @@ public class ProgramScope extends Scope {
|
|||||||
return "program";
|
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() {
|
public Scope getTypeDefScope() {
|
||||||
return typeDefsScope;
|
return typeDefsScope;
|
||||||
|
@ -8,6 +8,9 @@ public class ScopeRef extends SymbolRef {
|
|||||||
/** The ROOT scope of the program. */
|
/** The ROOT scope of the program. */
|
||||||
public static final ScopeRef ROOT = new ScopeRef("");
|
public static final ScopeRef ROOT = new ScopeRef("");
|
||||||
|
|
||||||
|
/** The scope holding type definitions. */
|
||||||
|
public static final ScopeRef TYPEDEFS = new ScopeRef("typedefs");
|
||||||
|
|
||||||
public ScopeRef(String fullName) {
|
public ScopeRef(String fullName) {
|
||||||
super(fullName);
|
super(fullName);
|
||||||
}
|
}
|
||||||
|
@ -1769,17 +1769,15 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitTypeNamedRef(KickCParser.TypeNamedRefContext ctx) {
|
public Object visitTypeNamedRef(KickCParser.TypeNamedRefContext ctx) {
|
||||||
|
|
||||||
Scope typeDefScope = program.getScope().getTypeDefScope();
|
Scope typeDefScope = program.getScope().getTypeDefScope();
|
||||||
Variable typeDefVariable = typeDefScope.getVariable(ctx.getText());
|
Variable typeDefVariable = typeDefScope.getVar(ctx.getText());
|
||||||
if(typeDefVariable != null) {
|
if(typeDefVariable != null) {
|
||||||
|
varDecl.setDeclType(typeDefVariable.getType());
|
||||||
if(typeDefVariable.getArraySpec() != null)
|
if(typeDefVariable.getArraySpec() != null)
|
||||||
// TODO: Handle typedef array of array correctly
|
varDecl.getDeclType().setArraySpec(typeDefVariable.getArraySpec());
|
||||||
throw new InternalError("Typedef with arrays not supported!");
|
|
||||||
if(typeDefVariable.isNoModify() || typeDefVariable.isVolatile() || typeDefVariable.isToNoModify() || typeDefVariable.isToVolatile())
|
if(typeDefVariable.isNoModify() || typeDefVariable.isVolatile() || typeDefVariable.isToNoModify() || typeDefVariable.isToVolatile())
|
||||||
// TODO: Handle type directives correctly
|
// TODO: Handle type directives correctly
|
||||||
throw new InternalError("Typedef with type directives not supported!");
|
throw new InternalError("Typedef with type directives not supported!");
|
||||||
varDecl.setDeclType(typeDefVariable.getType());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
throw new CompileError("Unknown type " + ctx.getText(), new StatementSource(ctx));
|
throw new CompileError("Unknown type " + ctx.getText(), new StatementSource(ctx));
|
||||||
@ -1851,9 +1849,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
this.visit(declArrayContext);
|
this.visit(declArrayContext);
|
||||||
}
|
}
|
||||||
String typedefName = ctx.NAME().getText();
|
String typedefName = ctx.NAME().getText();
|
||||||
final Variable typeDefVar = Variable.createPhiMaster(typedefName, varDecl.getEffectiveType(), typedefScope, defaultMemoryArea, currentDataSegment);
|
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, variableBuilderConfig);
|
||||||
typeDefVar.setArraySpec(varDecl.getEffectiveArraySpec());
|
final Variable typeDefVar = varBuilder.build();
|
||||||
typedefScope.add(typeDefVar);
|
|
||||||
scopeStack.pop();
|
scopeStack.pop();
|
||||||
varDecl.exitType();
|
varDecl.exitType();
|
||||||
return null;
|
return null;
|
||||||
|
@ -942,10 +942,25 @@ public class TestPrograms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
//@Test
|
||||||
//public void testTypedef3() throws IOException, URISyntaxException {
|
//public void testPointerConstTypedef() throws IOException, URISyntaxException {
|
||||||
// compileAndCompare("typedef-3");
|
// 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
|
@Test
|
||||||
public void testTypedef2() throws IOException, URISyntaxException {
|
public void testTypedef2() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("typedef-2");
|
compileAndCompare("typedef-2");
|
||||||
@ -1781,10 +1796,6 @@ public class TestPrograms {
|
|||||||
assertError("pointer-const-deep", "Deep const/volatile not supported");
|
assertError("pointer-const-deep", "Deep const/volatile not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPointerConstTypedef() throws IOException, URISyntaxException {
|
|
||||||
compileAndCompare("pointer-const-typedef");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPointerConst() throws IOException, URISyntaxException {
|
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
|
to:main::@1
|
||||||
main::@1: scope:[main] from main 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 )
|
[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
|
[7] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||||
[8] if((byte) main::i#1!=(byte) 7) goto main::@1
|
[8] if((byte) main::i#1!=(byte) 7) goto main::@1
|
||||||
to:main::@return
|
to:main::@return
|
||||||
|
@ -10,7 +10,7 @@ main: scope:[main] from @1
|
|||||||
to:main::@1
|
to:main::@1
|
||||||
main::@1: scope:[main] from main 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 )
|
(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)
|
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,6)
|
||||||
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,6)
|
(bool~) main::$0 ← (byte) main::i#1 != rangelast(0,6)
|
||||||
if((bool~) main::$0) goto main::@1
|
if((bool~) main::$0) goto main::@1
|
||||||
@ -30,7 +30,7 @@ SYMBOL TABLE SSA
|
|||||||
(label) @2
|
(label) @2
|
||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
(const byte*) SCREEN = (byte*)(number) $400
|
(const nomodify byte*) SCREEN = (byte*)(number) $400
|
||||||
(const byte*) a[(number) 7] = (byte*) "cml"
|
(const byte*) a[(number) 7] = (byte*) "cml"
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(bool~) main::$0
|
(bool~) main::$0
|
||||||
@ -94,7 +94,7 @@ main: scope:[main] from @1
|
|||||||
to:main::@1
|
to:main::@1
|
||||||
main::@1: scope:[main] from main 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 )
|
[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
|
[7] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||||
[8] if((byte) main::i#1!=(byte) 7) goto main::@1
|
[8] if((byte) main::i#1!=(byte) 7) goto main::@1
|
||||||
to:main::@return
|
to:main::@return
|
||||||
@ -156,7 +156,7 @@ main: {
|
|||||||
jmp __b1
|
jmp __b1
|
||||||
// main::@1
|
// main::@1
|
||||||
__b1:
|
__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
|
ldy.z i
|
||||||
lda a,y
|
lda a,y
|
||||||
sta SCREEN,y
|
sta SCREEN,y
|
||||||
@ -178,9 +178,9 @@ main: {
|
|||||||
.fill 3, 0
|
.fill 3, 0
|
||||||
|
|
||||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
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 ]
|
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 ,
|
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
|
||||||
|
|
||||||
REGISTER UPLIFT SCOPES
|
REGISTER UPLIFT SCOPES
|
||||||
@ -228,7 +228,7 @@ main: {
|
|||||||
jmp __b1
|
jmp __b1
|
||||||
// main::@1
|
// main::@1
|
||||||
__b1:
|
__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
|
lda a,x
|
||||||
sta SCREEN,x
|
sta SCREEN,x
|
||||||
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
// [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
||||||
@ -276,7 +276,7 @@ FINAL SYMBOL TABLE
|
|||||||
(label) @1
|
(label) @1
|
||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
(const byte*) SCREEN = (byte*) 1024
|
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||||
(const byte*) a[(number) 7] = (byte*) "cml"
|
(const byte*) a[(number) 7] = (byte*) "cml"
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
@ -316,7 +316,7 @@ main: {
|
|||||||
// main::@1
|
// main::@1
|
||||||
__b1:
|
__b1:
|
||||||
// SCREEN[i] = a[i]
|
// 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
|
lda a,x
|
||||||
sta SCREEN,x
|
sta SCREEN,x
|
||||||
// for(char i:0..6)
|
// for(char i:0..6)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
(label) @1
|
(label) @1
|
||||||
(label) @begin
|
(label) @begin
|
||||||
(label) @end
|
(label) @end
|
||||||
(const byte*) SCREEN = (byte*) 1024
|
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||||
(const byte*) a[(number) 7] = (byte*) "cml"
|
(const byte*) a[(number) 7] = (byte*) "cml"
|
||||||
(void()) main()
|
(void()) main()
|
||||||
(label) main::@1
|
(label) main::@1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user