Allow global-scope declarations

Function-local scope is still WIP, but you can now define things outside of function blocks.
This commit is contained in:
Curle 2020-09-13 23:41:46 +01:00
parent a27d3dd782
commit 264c50509e
Signed by: TheCurle
GPG Key ID: 2F2E62F0DA69A5AE
8 changed files with 95 additions and 28 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.idea
.vscode
out
bin

View File

@ -51,6 +51,7 @@ enum TokenTypes {
LI_RPARE, // ) LI_RPARE, // )
LI_AMP, // & LI_AMP, // &
LI_COM, // ,
TY_IDENTIFIER, // Identifier name. Variable, function, etc. TY_IDENTIFIER, // Identifier name. Variable, function, etc.
TY_NONE, // No return type. Literal void. TY_NONE, // No return type. Literal void.
@ -229,14 +230,16 @@ struct ASTNode* ParsePrimary(void);
struct ASTNode* ParseStatement(void); struct ASTNode* ParseStatement(void);
struct ASTNode* PrefixStatement(); struct ASTNode* PrefixStatement();
struct ASTNode* ParseFunction(); void ParseGlobals();
struct ASTNode* ParseFunction(int Type);
struct ASTNode* ParseCompound(); struct ASTNode* ParseCompound();
struct ASTNode* CallFunction(); struct ASTNode* CallFunction();
struct ASTNode* ReturnStatement(); struct ASTNode* ReturnStatement();
int ParsePointer(); int ParseOptionalPointer();
int ValueAt(int Type); int ValueAt(int Type);
int PointerTo(int Type); int PointerTo(int Type);
@ -331,7 +334,7 @@ void AsFunctionEpilogue(int ID);
* * * * D E C L A R A T I O N * * * * * * * * D E C L A R A T I O N * * * *
* * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * */
void BeginVariableDeclaration(void); void BeginVariableDeclaration(int Type);
struct ASTNode* ParseIdentifier(void); struct ASTNode* ParseIdentifier(void);
struct ASTNode* IfStatement(); struct ASTNode* IfStatement();

View File

@ -223,6 +223,10 @@ int Tokenise(struct Token* Token) {
Token->type = LI_AMP; Token->type = LI_AMP;
break; break;
case ',':
Token->type = LI_COM;
break;
case '=': case '=':
Char = NextChar(); Char = NextChar();
// If the next char is =, we have ==, the compare equality token. // If the next char is =, we have ==, the compare equality token.

View File

@ -79,14 +79,9 @@ int main(int argc, char* argv[]) {
AssemblerPreamble(); AssemblerPreamble();
while(1) { ParseGlobals();
Node = ParseFunction();
printf("\nBeginning assembler creation of new function %s\n", Symbols[Node->Value.ID].Name);
AssembleTree(Node, -1, 0);
if(CurrentToken.type == LI_EOF) //AsFunctionEpilogue();
break;
}
//Node = ParsePrecedenceASTNode(); //Node = ParsePrecedenceASTNode();
//printf("%d\n", ParseAST(Node)); //printf("%d\n", ParseAST(Node));

View File

@ -333,7 +333,7 @@ struct ASTNode* CallFunction() {
* * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * */
struct ASTNode* ParseStatement(void) { struct ASTNode* ParseStatement(void) {
int Type;
switch(CurrentToken.type) { switch(CurrentToken.type) {
@ -344,7 +344,9 @@ struct ASTNode* ParseStatement(void) {
case TY_LONG: case TY_LONG:
case TY_INT: case TY_INT:
printf("\t\tNew Variable: %s\n", CurrentIdentifier); printf("\t\tNew Variable: %s\n", CurrentIdentifier);
BeginVariableDeclaration(); Type = ParseOptionalPointer(CurrentToken.type);
VerifyToken(TY_IDENTIFIER, "ident");
BeginVariableDeclaration(Type);
return NULL; return NULL;
case TY_IDENTIFIER: case TY_IDENTIFIER:
@ -403,6 +405,38 @@ struct ASTNode* ParseCompound() {
} }
} }
void ParseGlobals() {
struct ASTNode* Tree;
int Type, FunctionComing;
printf("Parsing global definitions\n");
while(1) {
Type = ParseOptionalPointer();
//TODO: converge pathways on this block?
if(CurrentToken.type == KW_FUNC) {
VerifyToken(KW_FUNC, "::");
FunctionComing = 1;
}
VerifyToken(TY_IDENTIFIER, "ident");
if(FunctionComing && CurrentToken.type == LI_LPARE) {
printf("\tParsing function");
Tree = ParseFunction(Type);
printf("\nBeginning assembler creation of new function %s\n", Symbols[Tree->Value.ID].Name);
AssembleTree(Tree, -1, 0);
} else {
printf("\tParsing global variable declaration\n");
BeginVariableDeclaration(Type);
}
if(CurrentToken.type == LI_EOF)
break;
}
}
/* void ParseStatements() { /* void ParseStatements() {

View File

@ -36,15 +36,16 @@ int ValueAt(int Type) {
return -1; return -1;
} }
int ParsePointer() { int ParseOptionalPointer() {
int Type; int Type;
// TODO: THIS IS WRONG AND SHOULD NOT EXIST // TODO: THIS IS WRONG AND SHOULD NOT EXIST
// TY_CHAR is 21, RET_CHAR is 1. // TY_CHAR is 22, RET_CHAR is 1.
// Offset is 20. Rest are in order // Offset is 20. Rest are in order
if(CurrentToken.type >= TY_CHAR && CurrentToken.type <= TY_VOID) { if(CurrentToken.type >= TY_CHAR && CurrentToken.type <= TY_VOID) {
Type = CurrentToken.type - 20; Type = CurrentToken.type - 21;
printf("\t\tConverting a %d type to a %d type.\n", CurrentToken.type, Type);
} else { } else {
DieDecimal("Illegal type for pointerisation", CurrentToken.type); DieDecimal("Illegal type for pointerisation", CurrentToken.type);
} }

View File

@ -126,29 +126,37 @@ int TypesCompatible(int* Left, int* Right, int STRICT) {
* //TODO: int i = 5; * //TODO: int i = 5;
* *
*/ */
void BeginVariableDeclaration(void) { void BeginVariableDeclaration(int Type) {
int ID; int ID;
int Type = ParsePointer(CurrentToken.type);
//printf("type: %s\n", Types[Type]); //printf("type: %s\n", Types[Type]);
VerifyToken(TY_IDENTIFIER, "ident"); while(1) {
//printf("Identifier: %s\n", CurrentIdentifier); //printf("Identifier: %s\n", CurrentIdentifier);
printf("Adding symbol %s of type %s.\n", CurrentIdentifier, TypeNames[Type]);
ID = AddSymbol(CurrentIdentifier, Type, ST_VAR); ID = AddSymbol(CurrentIdentifier, Type, ST_VAR);
AsNewSymb(ID); AsNewSymb(ID);
VerifyToken(LI_SEMIC, ";"); if(CurrentToken.type == LI_SEMIC) {
printf("\tEnd of variables to declare in this statement\n");
Tokenise(&CurrentToken);
return;
}
if(CurrentToken.type == LI_COM) {
printf("\t\tStatement appears to continue. Integrating new variable.\n");
Tokenise(&CurrentToken);
VerifyToken(TY_IDENTIFIER, "ident");
continue;
}
DieDecimal("\nExpected ; after identifier, found", CurrentToken.type);
}
} }
struct ASTNode* ParseFunction() { struct ASTNode* ParseFunction(int Type) {
struct ASTNode* Tree; struct ASTNode* Tree;
struct ASTNode* FinalStatement; struct ASTNode* FinalStatement;
int SymbolSlot, BreakLabel, Type; int SymbolSlot, BreakLabel;
Type = ParsePointer(CurrentToken.type);
VerifyToken(KW_FUNC, "::");
VerifyToken(TY_IDENTIFIER, "ident");
printf("\nIdentified function %s\n", CurrentIdentifier); printf("\nIdentified function %s\n", CurrentIdentifier);

16
tests/globals Normal file
View File

@ -0,0 +1,16 @@
int x, y;
int* z;
void :: main() {
int a, b, c;
b = 3; c = 8;
a = b + c * 10;
PrintInteger(a);
x = 12; PrintInteger(x);
z = &x;
y = *z;
PrintInteger(y);
}