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:
parent
a27d3dd782
commit
264c50509e
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
out
|
||||||
|
bin
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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));
|
||||||
|
|
38
src/Parser.c
38
src/Parser.c
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
16
tests/globals
Normal 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);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user