1
0
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:
jespergravgaard 2020-03-30 08:35:22 +02:00
parent 5a8654b0e7
commit e3b54f34d7
10 changed files with 63 additions and 27 deletions

View File

@ -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());
}
/**

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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
View 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
View 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;
}

View File

@ -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

View File

@ -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)

View File

@ -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