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_AMP, // &
|
||||
LI_COM, // ,
|
||||
|
||||
TY_IDENTIFIER, // Identifier name. Variable, function, etc.
|
||||
TY_NONE, // No return type. Literal void.
|
||||
|
@ -229,14 +230,16 @@ struct ASTNode* ParsePrimary(void);
|
|||
struct ASTNode* ParseStatement(void);
|
||||
struct ASTNode* PrefixStatement();
|
||||
|
||||
struct ASTNode* ParseFunction();
|
||||
void ParseGlobals();
|
||||
|
||||
struct ASTNode* ParseFunction(int Type);
|
||||
struct ASTNode* ParseCompound();
|
||||
|
||||
|
||||
struct ASTNode* CallFunction();
|
||||
struct ASTNode* ReturnStatement();
|
||||
|
||||
int ParsePointer();
|
||||
int ParseOptionalPointer();
|
||||
int ValueAt(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 * * * *
|
||||
* * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
void BeginVariableDeclaration(void);
|
||||
void BeginVariableDeclaration(int Type);
|
||||
struct ASTNode* ParseIdentifier(void);
|
||||
|
||||
struct ASTNode* IfStatement();
|
||||
|
|
|
@ -223,6 +223,10 @@ int Tokenise(struct Token* Token) {
|
|||
Token->type = LI_AMP;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
Token->type = LI_COM;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
Char = NextChar();
|
||||
// If the next char is =, we have ==, the compare equality token.
|
||||
|
|
|
@ -79,14 +79,9 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
AssemblerPreamble();
|
||||
|
||||
while(1) {
|
||||
Node = ParseFunction();
|
||||
printf("\nBeginning assembler creation of new function %s\n", Symbols[Node->Value.ID].Name);
|
||||
AssembleTree(Node, -1, 0);
|
||||
ParseGlobals();
|
||||
|
||||
if(CurrentToken.type == LI_EOF)
|
||||
break;
|
||||
}
|
||||
//AsFunctionEpilogue();
|
||||
|
||||
//Node = ParsePrecedenceASTNode();
|
||||
//printf("%d\n", ParseAST(Node));
|
||||
|
|
38
src/Parser.c
38
src/Parser.c
|
@ -333,7 +333,7 @@ struct ASTNode* CallFunction() {
|
|||
* * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
struct ASTNode* ParseStatement(void) {
|
||||
|
||||
int Type;
|
||||
|
||||
switch(CurrentToken.type) {
|
||||
|
||||
|
@ -344,7 +344,9 @@ struct ASTNode* ParseStatement(void) {
|
|||
case TY_LONG:
|
||||
case TY_INT:
|
||||
printf("\t\tNew Variable: %s\n", CurrentIdentifier);
|
||||
BeginVariableDeclaration();
|
||||
Type = ParseOptionalPointer(CurrentToken.type);
|
||||
VerifyToken(TY_IDENTIFIER, "ident");
|
||||
BeginVariableDeclaration(Type);
|
||||
return NULL;
|
||||
|
||||
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() {
|
||||
|
|
|
@ -36,15 +36,16 @@ int ValueAt(int Type) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ParsePointer() {
|
||||
int ParseOptionalPointer() {
|
||||
|
||||
int Type;
|
||||
// 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
|
||||
|
||||
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 {
|
||||
DieDecimal("Illegal type for pointerisation", CurrentToken.type);
|
||||
}
|
||||
|
|
|
@ -126,29 +126,37 @@ int TypesCompatible(int* Left, int* Right, int STRICT) {
|
|||
* //TODO: int i = 5;
|
||||
*
|
||||
*/
|
||||
void BeginVariableDeclaration(void) {
|
||||
void BeginVariableDeclaration(int Type) {
|
||||
int ID;
|
||||
int Type = ParsePointer(CurrentToken.type);
|
||||
//printf("type: %s\n", Types[Type]);
|
||||
|
||||
VerifyToken(TY_IDENTIFIER, "ident");
|
||||
while(1) {
|
||||
//printf("Identifier: %s\n", CurrentIdentifier);
|
||||
|
||||
printf("Adding symbol %s of type %s.\n", CurrentIdentifier, TypeNames[Type]);
|
||||
ID = AddSymbol(CurrentIdentifier, Type, ST_VAR);
|
||||
AsNewSymb(ID);
|
||||
|
||||
VerifyToken(LI_SEMIC, ";");
|
||||
if(CurrentToken.type == LI_SEMIC) {
|
||||
printf("\tEnd of variables to declare in this statement\n");
|
||||
Tokenise(&CurrentToken);
|
||||
return;
|
||||
}
|
||||
|
||||
struct ASTNode* ParseFunction() {
|
||||
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(int Type) {
|
||||
struct ASTNode* Tree;
|
||||
struct ASTNode* FinalStatement;
|
||||
int SymbolSlot, BreakLabel, Type;
|
||||
|
||||
Type = ParsePointer(CurrentToken.type);
|
||||
|
||||
VerifyToken(KW_FUNC, "::");
|
||||
VerifyToken(TY_IDENTIFIER, "ident");
|
||||
int SymbolSlot, BreakLabel;
|
||||
|
||||
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