Compare commits

..

No commits in common. "a27d3dd7829211f22c982c7313fab5a7bd15c888" and "c2b396b85357adfd511798ae71d58b0de92adfaf" have entirely different histories.

14 changed files with 57 additions and 257 deletions

View File

@ -16,8 +16,6 @@
extern_ struct SymbolTable Symbols[SYMBOLS];
extern_ char* TypeNames[9];
extern_ char* TokenStrings[];
extern_ char* TokenNames[];

View File

@ -16,7 +16,6 @@
* TYpes are prefixed TY.
* CoMParisons are prefixed CMP.
*
*
* NOTE: Tokens are different from Syntax Operations!
*
* Tokens should represent the characters that invoke them,
@ -50,8 +49,6 @@ enum TokenTypes {
LI_LPARE, // (
LI_RPARE, // )
LI_AMP, // &
TY_IDENTIFIER, // Identifier name. Variable, function, etc.
TY_NONE, // No return type. Literal void.
TY_CHAR, // "char" type keyword
@ -97,9 +94,6 @@ enum SyntaxOps {
OP_ASSIGN, // Assign an l-value
OP_ADDRESS, // Fetch the address of a var
OP_DEREF, // Get the value of the address in a pointer
TERM_INTLITERAL, // Integer Literal. This is a virtual operation, so it's a terminal.
REF_IDENT, // Reference (read) an identifier (variable).
@ -155,17 +149,11 @@ struct SymbolTable {
* //TODO: Move back into TokenTypes
*/
enum DataTypes {
RET_NONE, // No return type. Literal void.
RET_CHAR, // "char" type keyword
RET_INT, // "int" type keyword
RET_LONG, // "long" type keyword
RET_VOID, // "void" type keyword
// Pointer types
PTR_CHAR,
PTR_INT,
PTR_LONG,
PTR_VOID,
RET_NONE, // No return type. Literal void.
RET_CHAR, // "char" type keyword
RET_INT, // "int" type keyword
RET_LONG, // "long" type keyword
RET_VOID, // "void" type keyword
};
@ -224,10 +212,8 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence);
int ParseAST(struct ASTNode* Node);
struct ASTNode* ParsePrimary(void);
//void ParseStatements(void);
struct ASTNode* ParseStatement(void);
struct ASTNode* PrefixStatement();
struct ASTNode* ParseFunction();
struct ASTNode* ParseCompound();
@ -236,9 +222,7 @@ struct ASTNode* ParseCompound();
struct ASTNode* CallFunction();
struct ASTNode* ReturnStatement();
int ParsePointer();
int ValueAt(int Type);
int PointerTo(int Type);
int ParseType(int Token);
int ParseTokenToOperation(int Token);
@ -295,9 +279,6 @@ int AsDiv(int Left, int Right);
int AsLdVar(int ID);
int AsStrVar(int Register, int ID);
int AsDeref(int Reg, int Type);
int AsAddr(int ID);
void AsNewSymb(int ID);
int AsEqual(int Left, int Right);

View File

@ -26,6 +26,8 @@ static char* ByteRegisters[4] = { "%r8b", "%r9b", "%r10b", "%r11b" };
static char* Comparisons[6] = { "sete", "setne", "setl", "setg", "setle", "setge" };
static char* InvComparisons[6] = { "jne", "je", "jge", "jle", "jg", "jl"};
static char* Types[5] = { "none", "char", "int", "long", "void" };
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * R O O T O F A S S E M B L E R * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
@ -83,12 +85,6 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
case OP_DIVIDE:
return AsDiv(LeftVal, RightVal);
case OP_ADDRESS:
return AsAddr(Node->Value.ID);
case OP_DEREF:
return AsDeref(LeftVal, Node->Left->ExprType);
case OP_ASSIGN:
return RightVal;
@ -360,22 +356,18 @@ int AsLdVar(int ID) {
break;
case RET_LONG:
case PTR_CHAR:
case PTR_INT:
case PTR_LONG:
case PTR_VOID:
fprintf(OutputFile, "\tmovq\t%s(%%rip), %s\n", Symbols[ID].Name, Registers[Reg]);
break;
default:
DieMessage("Bad type for loading", TypeNames[Symbols[ID].Type]);
DieMessage("Bad type for loading", Types[Symbols[ID].Type]);
}
return Reg;
}
int AsStrVar(int Register, int ID) {
printf("\tStoring contents of %s into %s, type %d\n", Registers[Register], Symbols[ID].Name, Symbols[ID].Type);
printf("\tStoring contents of %s into %s\n", Registers[Register], Symbols[ID].Name);
switch(Symbols[ID].Type) {
case RET_CHAR:
@ -388,42 +380,14 @@ int AsStrVar(int Register, int ID) {
break;
case RET_LONG:
case PTR_CHAR:
case PTR_INT:
case PTR_LONG:
case PTR_VOID:
fprintf(OutputFile, "\tmovq\t%s, %s(%%rip)\n", Registers[Register], Symbols[ID].Name);
break;
default:
DieMessage("Bad type for saving", TypeNames[Symbols[ID].Type]);
}
return Register;
}
int AsAddr(int ID) {
int Register = RetrieveRegister();
printf("\tSaving pointer of %s into %s\n", Symbols[ID].Name, Registers[Register]);
fprintf(OutputFile, "\tleaq\t%s(%%rip), %s\n", Symbols[ID].Name, Registers[Register]);
return Register;
}
int AsDeref(int Reg, int Type) {
printf("\tDereferencing %s\n", Registers[Reg]);
switch(Type) {
case PTR_CHAR:
fprintf(OutputFile, "\tmovzbq\t(%s), %s\n", Registers[Reg], Registers[Reg]);
break;
case PTR_INT:
case PTR_LONG:
fprintf(OutputFile, "\tmovq\t(%s), %s\n", Registers[Reg], Registers[Reg]);
break;
DieMessage("Bad type for saving", Types[Symbols[ID].Type]);
}
return Reg;
return Register;
}
void AsNewSymb(int ID) {
@ -468,7 +432,7 @@ int AsReturn(int Register, int FuncID) {
break;
default:
DieMessage("Bad function type in generating return", TypeNames[Symbols[FuncID].Type]);
DieMessage("Bad function type in generating return", Types[Symbols[FuncID].Type]);
}

View File

@ -218,10 +218,6 @@ int Tokenise(struct Token* Token) {
case '/':
Token->type = AR_SLASH;
break;
case '&':
Token->type = LI_AMP;
break;
case '=':
Char = NextChar();

View File

@ -35,8 +35,6 @@ char* TokenNames[] = {
"Logical Block Start",
"Logical Block End",
"Dereference operator",
"Identifier",
"None Type",
"Char Type",
@ -54,8 +52,21 @@ char* TokenNames[] = {
"Return keyword"
};
char* TypeNames[9] = { "none", "char", "int", "long", "void", "charptr", "intptr", "longptr", "voidptr"};
static void TokeniseFile() {
struct Token Token;
while(Tokenise(&Token)) {
printf("Token %s", TokenStrings[Token.type]);
if(Token.type == LI_INT) {
printf(", value %d", Token.value);
}
printf("\n");
}
}
int main(int argc, char* argv[]) {
Line = 1;

View File

@ -99,7 +99,7 @@ int ParseTokenToOperation(int Token) {
*
*/
struct ASTNode* ParsePrimary(void) {
static struct ASTNode* ParsePrimary(void) {
struct ASTNode* Node;
int ID;
@ -174,7 +174,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
int LeftType, RightType;
int NodeType;
LeftNode = PrefixStatement();
LeftNode = ParsePrimary();
NodeType = CurrentToken.type;
if(NodeType == LI_SEMIC || NodeType == LI_RPARE)

View File

@ -1,66 +0,0 @@
/*************/
/*GEMWIRE */
/* ERYTHRO*/
/*************/
#include <Defs.h>
#include <Data.h>
int PointerTo(int Type) {
printf("\t\tPointerising a %s\n", TypeNames[Type]);
// As it stands, the conversion between
// RET and PTR is +4.
// TODO: if we add types, increase this number
// TODO: Make this a proper translation table
// TODO: More checks! This can go wrong easily!
if(Type >= RET_CHAR && Type <= RET_VOID) {
return Type + 4;
} else {
DieDecimal("Unable to create a pointer to the desired type", Type);
}
return -1;
}
int ValueAt(int Type) {
printf("\t\tDereferencing a %s\n", TypeNames[Type]);
//TODO: this is still bullshittery!
if(Type >= PTR_CHAR && Type <= PTR_VOID) {
return Type - 4;
} else {
DieDecimal("Unable to dereference type", Type);
}
return -1;
}
int ParsePointer() {
int Type;
// TODO: THIS IS WRONG AND SHOULD NOT EXIST
// TY_CHAR is 21, RET_CHAR is 1.
// Offset is 20. Rest are in order
if(CurrentToken.type >= TY_CHAR && CurrentToken.type <= TY_VOID) {
Type = CurrentToken.type - 20;
} else {
DieDecimal("Illegal type for pointerisation", CurrentToken.type);
}
// Recursively scan more *s
// This makes things like:
// x = **y;
// possible.
while(1) {
Tokenise(&CurrentToken);
printf("\t\t\tType on parsing is %d\n", CurrentToken.type);
if(CurrentToken.type != AR_STAR)
break;
Type = PointerTo(Type);
}
return Type;
}

View File

@ -20,11 +20,28 @@
*
*/
static int TypeSize[9] = { 0, 1, 4, 8, 0, 8, 8, 8, 8}; // in BYTES
static char* Types[5] = { "none", "char", "int", "long", "void" };
static int TypeSize[5] = { 0, 1, 4, 8, 0}; // in BYTES
int ParseType(int Token) {
switch(Token) {
case TY_CHAR:
return RET_CHAR;
case TY_VOID:
return RET_VOID;
case TY_INT:
return RET_INT;
default:
DieDecimal("Illegal variable type", Token);
}
}
int PrimitiveSize(int Type) {
if(Type < RET_NONE || Type > PTR_VOID)
DieDecimal("Checking size of bad data type", Type);
if(Type < RET_NONE || Type > RET_VOID)
DieMessage("Checking size of bad data type", Types[Type]);
return TypeSize[Type];
}
@ -128,9 +145,10 @@ int TypesCompatible(int* Left, int* Right, int STRICT) {
*/
void BeginVariableDeclaration(void) {
int ID;
int Type = ParsePointer(CurrentToken.type);
int Type = ParseType(CurrentToken.type);
//printf("type: %s\n", Types[Type]);
Tokenise(&CurrentToken);
VerifyToken(TY_IDENTIFIER, "ident");
//printf("Identifier: %s\n", CurrentIdentifier);
@ -145,8 +163,8 @@ struct ASTNode* ParseFunction() {
struct ASTNode* FinalStatement;
int SymbolSlot, BreakLabel, Type;
Type = ParsePointer(CurrentToken.type);
Type = ParseType(CurrentToken.type);
Tokenise(&CurrentToken);
VerifyToken(KW_FUNC, "::");
VerifyToken(TY_IDENTIFIER, "ident");
@ -233,7 +251,7 @@ struct ASTNode* ParseIdentifier() {
VerifyToken(TY_IDENTIFIER, "ident");
printf("\t\tAfter parsing, the identifier name is %s, id %d in the symbol table.\n", CurrentIdentifier, FindSymbol(CurrentIdentifier));
printf("After parsing, the identifier name is %s, id %d in the symbol table.\n", CurrentIdentifier, FindSymbol(CurrentIdentifier));
if(CurrentToken.type == LI_LPARE)
return CallFunction();
@ -367,41 +385,4 @@ struct ASTNode* PrintStatement(void) {
return Tree;
}
struct ASTNode* PrefixStatement() {
struct ASTNode* Tree;
switch (CurrentToken.type) {
case LI_AMP:
Tokenise(&CurrentToken);
// To allow things like:
// x = &&y;
// We need to recursively parse prefixes;
Tree = PrefixStatement();
if(Tree->Operation != REF_IDENT)
Die("& must be followed by another & or an identifier.");
Tree->Operation = OP_ADDRESS;
Tree->ExprType = PointerTo(Tree->ExprType);
break;
case AR_STAR:
Tokenise(&CurrentToken);
Tree = PrefixStatement();
if(Tree->Operation != REF_IDENT && Tree->Operation != OP_DEREF)
Die("* must be followed by another * or an identifier.");
Tree = ConstructASTBranch(OP_DEREF, ValueAt(Tree->ExprType), Tree, 0);
break;
default:
Tree = ParsePrimary();
}
return Tree;
}

View File

@ -1,4 +1,4 @@
void :: main() {
{
int x;
x = 0;

View File

@ -11,6 +11,5 @@ void :: main() {
PrintInteger(Result);
PrintInteger(Testings(10) + i);
PrintInteger(Testings(10) + 10);
}

View File

@ -1,19 +0,0 @@
int :: Testings() {
return (40);
}
void :: main() {
int Result;
PrintInteger(10);
Result = Testings(10);
PrintInteger(Result);
int i;
for(i = 0; i < 5; i = i + 1) {
PrintInteger(Testings(10) + i);
}
}

View File

@ -1,10 +0,0 @@
void :: main() {
int i;
for(i = 0; i < 5; i = i + 1) {
PrintInteger(i);
}
}

View File

@ -1,22 +0,0 @@
int :: main() {
char a;
char *b;
char c;
int d;
int *e;
int f;
a= 18;
PrintInteger(a);
b= &a;
c= *b;
PrintInteger(c);
d= 12;
PrintInteger(d);
e= &d;
f= *e;
PrintInteger(f);
return(0);
}

View File

@ -1,13 +0,0 @@
void :: main() {
int x;
int y;
int m;
x = 5;
y = 50;
m = 300;
print m;
print y;
print x;
}