CLion reformatting pass, finish struct implementation
This commit is contained in:
parent
ac8c0ed9c7
commit
537246daae
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
project(Erythro C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_executable(Erythro
|
||||
include/Data.h
|
||||
include/Defs.h
|
||||
src/Assembler.c
|
||||
src/Delegate.c
|
||||
src/Dump.c
|
||||
src/Lexer.c
|
||||
src/Main.c
|
||||
src/Parser.c
|
||||
src/Pointers.c
|
||||
src/Statements.c
|
||||
src/Symbols.c
|
||||
src/Types.c)
|
|
@ -4,6 +4,7 @@
|
|||
/*************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Defs.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/*************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
@ -117,32 +118,32 @@ enum SyntaxOps {
|
|||
OP_BOOLOR, // Boolean OR two statements
|
||||
OP_BOOLAND, // Boolean AND two statements
|
||||
OP_BITOR, // Bitwise OR a number
|
||||
OP_BITXOR, // Bitwise XOR a number
|
||||
OP_BITXOR = 5, // Bitwise XOR a number
|
||||
OP_BITAND, // Bitwise AND a number
|
||||
|
||||
OP_EQUAL, // Compare equality
|
||||
OP_INEQ, // Compare inequality
|
||||
OP_LESS, // Less than?
|
||||
OP_GREAT, // Greater than?
|
||||
OP_GREAT = 10, // Greater than?
|
||||
OP_LESSE, // Less than or Equal to?
|
||||
OP_GREATE, // Greater than or Equal to?
|
||||
|
||||
OP_SHIFTL, // Arithmetic Shift Left (Multiply by 2)
|
||||
OP_SHIFTR, // Arithmetic Shift Right (Divide by 2)
|
||||
|
||||
OP_ADD, // Add two numbers.
|
||||
OP_ADD = 15, // Add two numbers.
|
||||
OP_SUBTRACT, // Subtract two numbers.
|
||||
OP_MULTIPLY, // Multiply two numbers.
|
||||
OP_DIVIDE, // Divide two numbers.
|
||||
|
||||
OP_PREINC, // Increment var before reference.
|
||||
OP_PREDEC, // Decrement var before reference.
|
||||
OP_PREDEC = 20, // Decrement var before reference.
|
||||
OP_POSTINC, // Increment var after reference.
|
||||
OP_POSTDEC, // Decrement var after reference.
|
||||
|
||||
OP_BITNOT, // Invert a number bitwise
|
||||
OP_BOOLNOT, // Invert a statement logically
|
||||
OP_NEGATE, // Negate a number (turn a positive number negative)
|
||||
OP_NEGATE = 25, // Negate a number (turn a positive number negative)
|
||||
|
||||
OP_BOOLCONV, // Convert an expression to a boolean.s
|
||||
|
||||
|
@ -150,7 +151,7 @@ enum SyntaxOps {
|
|||
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.
|
||||
TERM_STRLITERAL, // String Literal. Also terminal.
|
||||
TERM_STRLITERAL = 30, // String Literal. Also terminal.
|
||||
|
||||
REF_IDENT, // Reference (read) an identifier (variable).
|
||||
|
||||
|
@ -158,14 +159,14 @@ enum SyntaxOps {
|
|||
OP_SCALE, // We have a pointer that needs to be scaled!
|
||||
|
||||
OP_CALL, // Call a function
|
||||
OP_RET, // Return from a function
|
||||
OP_RET = 35, // Return from a function
|
||||
|
||||
OP_COMP, // Compound statements need a way to be "glued" together. This is one of those mechanisms
|
||||
OP_IF, // If statement
|
||||
OP_LOOP, // FOR, WHILE
|
||||
OP_PRINT, // Print statement
|
||||
|
||||
OP_FUNC, // Define a function
|
||||
OP_FUNC = 40, // Define a function
|
||||
};
|
||||
|
||||
|
||||
|
@ -268,9 +269,13 @@ enum StructureType {
|
|||
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
char* Suffixate(char* String, char Suffix);
|
||||
|
||||
char* Compile(char* InputFile);
|
||||
|
||||
char* Assemble(char* InputFile);
|
||||
|
||||
void Link(char* Output, char* Objects[]);
|
||||
|
||||
void DisplayUsage(char* ProgName);
|
||||
|
||||
|
||||
|
@ -282,9 +287,11 @@ void DisplayUsage(char* ProgName);
|
|||
void Tokenise();
|
||||
|
||||
void VerifyToken(int Type, char* TokenExpected);
|
||||
|
||||
void RejectToken(struct Token* Token);
|
||||
|
||||
static int ReadIdentifier(int Char, char* Buffer, int Limit);
|
||||
|
||||
static int ReadKeyword(char* Str);
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * *
|
||||
|
@ -294,9 +301,11 @@ static int ReadKeyword(char* Str);
|
|||
struct ASTNode* MutateType(struct ASTNode* Tree, int RightType, int Operation);
|
||||
|
||||
int TypeIsInt(int Type);
|
||||
|
||||
int TypeIsPtr(int Type);
|
||||
|
||||
char* TypeNames(int Type);
|
||||
|
||||
int TypeSize(int Type, struct SymbolTableEntry* Composite);
|
||||
|
||||
|
||||
|
@ -314,7 +323,8 @@ struct ASTNode* ConstructASTNode(int Operation, int Type,
|
|||
|
||||
struct ASTNode* ConstructASTLeaf(int Operation, int Type, struct SymbolTableEntry* Symbol, int IntValue);
|
||||
|
||||
struct ASTNode* ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue);
|
||||
struct ASTNode*
|
||||
ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue);
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
@ -325,25 +335,35 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence);
|
|||
|
||||
|
||||
struct ASTNode* ParsePrimary(void);
|
||||
|
||||
struct ASTNode* ParseStatement(void);
|
||||
|
||||
struct ASTNode* PrefixStatement();
|
||||
|
||||
struct ASTNode* PostfixStatement();
|
||||
|
||||
void ParseGlobals();
|
||||
|
||||
struct ASTNode* ParseFunction(int Type);
|
||||
|
||||
struct ASTNode* ParseCompound();
|
||||
|
||||
struct SymbolTableEntry* BeginStructDeclaration();
|
||||
|
||||
struct ASTNode* GetExpressionList();
|
||||
|
||||
struct ASTNode* CallFunction();
|
||||
|
||||
struct ASTNode* ReturnStatement();
|
||||
|
||||
int ParseOptionalPointer(struct SymbolTableEntry** Composite);
|
||||
|
||||
int ValueAt(int Type);
|
||||
|
||||
int PointerTo(int Type);
|
||||
|
||||
struct ASTNode* AccessArray();
|
||||
|
||||
struct ASTNode* AccessMember(bool Deref);
|
||||
|
||||
int ParseTokenToOperation(int Token);
|
||||
|
@ -351,35 +371,45 @@ int ParseTokenToOperation(int Token);
|
|||
struct ASTNode* PrintStatement(void);
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* * * * * * S Y M B O L T A B L E * * * * * *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
void DumpAllLists();
|
||||
|
||||
void DumpList(struct SymbolTableEntry* List);
|
||||
|
||||
struct SymbolTableEntry* FindSymbol(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindLocal(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindGlobal(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindStruct(char* Symbol);
|
||||
|
||||
struct SymbolTableEntry* FindMember(char* Symbol);
|
||||
|
||||
void AppendSymbol(struct SymbolTableEntry** Head, struct SymbolTableEntry** Tail, struct SymbolTableEntry* Node);
|
||||
|
||||
void FreeLocals();
|
||||
|
||||
void ClearTables();
|
||||
|
||||
struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Storage, int Length, int SinkOffset, struct SymbolTableEntry* CompositeType);
|
||||
struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Storage, int Length, int SinkOffset,
|
||||
struct SymbolTableEntry* CompositeType);
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* * * * C O N T R O L S T A T U S * * * *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
void Die(char* Error);
|
||||
|
||||
void DieMessage(char* Error, char* Reason);
|
||||
|
||||
void DieDecimal(char* Error, int Number);
|
||||
|
||||
void DieChar(char* Error, int Char);
|
||||
|
||||
void DieBinary(char* Error, int Number);
|
||||
|
||||
|
||||
|
@ -396,62 +426,94 @@ int RetrieveRegister();
|
|||
void DeallocateRegister(int Register);
|
||||
|
||||
int PrimitiveSize(int Type);
|
||||
|
||||
int AsAlignMemory(int Type, int Offset, int Direction);
|
||||
|
||||
int AsLoad(int Value);
|
||||
|
||||
int AsAdd(int Left, int Right);
|
||||
|
||||
int AsMul(int Left, int Right);
|
||||
|
||||
int AsSub(int Left, int Right);
|
||||
|
||||
int AsDiv(int Left, int Right);
|
||||
|
||||
int AsLdGlobalVar(struct SymbolTableEntry* Entry, int Operation);
|
||||
|
||||
int AsLdLocalVar(struct SymbolTableEntry* Entry, int Operation);
|
||||
|
||||
int AsStrGlobalVar(struct SymbolTableEntry* Entry, int Register);
|
||||
|
||||
int AsStrLocalVar(struct SymbolTableEntry* Entry, int Register);
|
||||
|
||||
int AsCalcOffset(int Type);
|
||||
|
||||
void AsNewStackFrame();
|
||||
|
||||
int AsDeref(int Reg, int Type);
|
||||
|
||||
int AsStrDeref(int Register1, int Register2, int Type);
|
||||
|
||||
int AsAddr(struct SymbolTableEntry* Entry);
|
||||
|
||||
void AsGlobalSymbol(struct SymbolTableEntry* Entry);
|
||||
|
||||
int AsNewString(char* Value);
|
||||
|
||||
|
||||
int AsLoadString(int ID);
|
||||
|
||||
int AsEqual(int Left, int Right);
|
||||
|
||||
int AsIneq(int Left, int Right);
|
||||
|
||||
int AsLess(int Left, int Right);
|
||||
|
||||
int AsGreat(int Left, int Right);
|
||||
|
||||
int AsLessE(int Left, int Right);
|
||||
|
||||
int AsGreatE(int Left, int Right);
|
||||
|
||||
int AsBitwiseAND(int Left, int Right);
|
||||
|
||||
int AsBitwiseOR(int Left, int Right);
|
||||
|
||||
int AsBitwiseXOR(int Left, int Right);
|
||||
|
||||
int AsNegate(int Register);
|
||||
|
||||
int AsInvert(int Register);
|
||||
|
||||
int AsBooleanNOT(int Register);
|
||||
|
||||
int AsShiftLeft(int Left, int Right);
|
||||
|
||||
int AsShiftRight(int Left, int Right);
|
||||
|
||||
int AsBooleanConvert(int Register, int Operation, int Label);
|
||||
|
||||
int AsCompareJmp(int Operation, int RegisterLeft, int RegisterRight, int Label);
|
||||
|
||||
int AsCompare(int Operation, int RegisterLeft, int RegisterRight);
|
||||
|
||||
int AsIf(struct ASTNode* Node);
|
||||
|
||||
int NewLabel(void);
|
||||
|
||||
void AsJmp(int Label);
|
||||
|
||||
void AsLabel(int Label);
|
||||
|
||||
int AsShl(int Register, int Val);
|
||||
|
||||
int AsReturn(struct SymbolTableEntry* Entry, int Register);
|
||||
|
||||
int AsCallWrapper(struct ASTNode* Node);
|
||||
|
||||
void AsCopyArgs(int Register, int Position);
|
||||
|
||||
int AsCall(struct SymbolTableEntry* Entry, int Args);
|
||||
|
||||
int AsWhile(struct ASTNode* Node);
|
||||
|
@ -459,7 +521,9 @@ int AsWhile(struct ASTNode* Node);
|
|||
void AssemblerPrint(int Register);
|
||||
|
||||
void AssemblerPreamble();
|
||||
|
||||
void AsFunctionPreamble(struct SymbolTableEntry* Entry);
|
||||
|
||||
void AsFunctionEpilogue(struct SymbolTableEntry* Entry);
|
||||
|
||||
|
||||
|
@ -468,10 +532,13 @@ void AsFunctionEpilogue(struct SymbolTableEntry* Entry);
|
|||
* * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
struct SymbolTableEntry* BeginVariableDeclaration(int Type, struct SymbolTableEntry* Composite, int Scope);
|
||||
|
||||
struct ASTNode* ParseIdentifier(void);
|
||||
|
||||
struct ASTNode* IfStatement();
|
||||
|
||||
struct ASTNode* WhileStatement();
|
||||
|
||||
struct ASTNode* ForStatement();
|
||||
|
||||
|
||||
|
|
127
src/Assembler.c
127
src/Assembler.c
|
@ -119,9 +119,12 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
|||
// We can (ab)use the powers of 2 to do
|
||||
// efficient scaling with bitshifting.
|
||||
switch (Node->Size) {
|
||||
case 2: return AsShl(LeftVal, 1);
|
||||
case 4: return AsShl(LeftVal, 2);
|
||||
case 8: return AsShl(LeftVal, 3);
|
||||
case 2:
|
||||
return AsShl(LeftVal, 1);
|
||||
case 4:
|
||||
return AsShl(LeftVal, 2);
|
||||
case 8:
|
||||
return AsShl(LeftVal, 3);
|
||||
|
||||
default:
|
||||
RightVal = AsLoad(Node->Size);
|
||||
|
@ -146,8 +149,10 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
|||
else
|
||||
return AsStrGlobalVar(Node->Right->Symbol, LeftVal);
|
||||
|
||||
case OP_DEREF: return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType);
|
||||
default: DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
|
||||
case OP_DEREF:
|
||||
return AsStrDeref(LeftVal, RightVal, Node->Right->ExprType);
|
||||
default:
|
||||
DieDecimal("Can't ASSIGN in AssembleTree: ", Node->Operation);
|
||||
}
|
||||
|
||||
case OP_WIDEN:
|
||||
|
@ -172,6 +177,10 @@ int AssembleTree(struct ASTNode* Node, int Register, int ParentOp) {
|
|||
|
||||
|
||||
case REF_IDENT:
|
||||
if (TypeIsPtr(Node->ExprType)) {
|
||||
return AsAddr(Node->Symbol);
|
||||
}
|
||||
|
||||
if (Node->RVal || ParentOp == OP_DEREF) {
|
||||
if (Node->Symbol->Storage == SC_LOCAL || Node->Symbol->Storage == SC_PARAM)
|
||||
return AsLdLocalVar(Node->Symbol, Node->Operation);
|
||||
|
@ -329,8 +338,11 @@ int NewLabel(void) {
|
|||
*/
|
||||
int AsAlignMemory(int Type, int Offset, int Direction) {
|
||||
switch (Type) {
|
||||
case RET_CHAR: return Offset;
|
||||
case RET_INT: case RET_LONG: break;
|
||||
case RET_CHAR:
|
||||
return Offset;
|
||||
case RET_INT:
|
||||
case RET_LONG:
|
||||
break;
|
||||
default:
|
||||
DieDecimal("Unable to align type", Type);
|
||||
}
|
||||
|
@ -391,7 +403,8 @@ int AsCompareJmp(int Operation, int RegisterLeft, int RegisterRight, int Label)
|
|||
if (Operation < OP_EQUAL || Operation > OP_GREATE)
|
||||
Die("Bad Operation in AsCompareJmp");
|
||||
|
||||
printf("\tBranching on comparison of registers %d & %d, with operation %s\n\n", RegisterLeft, RegisterRight, Comparisons[Operation - OP_EQUAL]);
|
||||
printf("\tBranching on comparison of registers %d & %d, with operation %s\n\n", RegisterLeft, RegisterRight,
|
||||
Comparisons[Operation - OP_EQUAL]);
|
||||
|
||||
fprintf(OutputFile, "\tcmpq\t%s, %s\n", Registers[RegisterRight], Registers[RegisterLeft]);
|
||||
fprintf(OutputFile, "\t%s\tL%d\n", InvComparisons[Operation - OP_EQUAL], Label);
|
||||
|
@ -548,18 +561,22 @@ int AsLdGlobalVar(struct SymbolTableEntry* Entry, int Operation) {
|
|||
case 1:
|
||||
switch (Operation) {
|
||||
case OP_PREINC:
|
||||
fprintf(OutputFile, "\tincb\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tincb\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
case OP_PREDEC:
|
||||
fprintf(OutputFile, "\tdecb\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tdecb\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(OutputFile, "\tmovzbq\t%s(\%%rip), %s\n", Entry->Name, Registers[Reg]);
|
||||
|
||||
switch (Operation) {
|
||||
case OP_POSTINC:
|
||||
fprintf(OutputFile, "\tincb\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tincb\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
case OP_POSTDEC:
|
||||
fprintf(OutputFile, "\tdecb\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tdecb\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -567,36 +584,44 @@ int AsLdGlobalVar(struct SymbolTableEntry* Entry, int Operation) {
|
|||
case 4:
|
||||
switch (Operation) {
|
||||
case OP_PREINC:
|
||||
fprintf(OutputFile, "\tincl\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tincl\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
case OP_PREDEC:
|
||||
fprintf(OutputFile, "\tdecl\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tdecl\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(OutputFile, "\tmovslq\t%s(\%%rip), %s\n", Entry->Name, Registers[Reg]);
|
||||
|
||||
switch (Operation) {
|
||||
case OP_POSTINC:
|
||||
fprintf(OutputFile, "\tincl\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tincl\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
case OP_POSTDEC:
|
||||
fprintf(OutputFile, "\tdecl\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tdecl\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 8:
|
||||
switch (Operation) {
|
||||
case OP_PREINC:
|
||||
fprintf(OutputFile, "\tincq\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tincq\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
case OP_PREDEC:
|
||||
fprintf(OutputFile, "\tdecq\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tdecq\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(OutputFile, "\tmovq\t%s(\%%rip), %s\n", Entry->Name, Registers[Reg]);
|
||||
|
||||
switch (Operation) {
|
||||
case OP_POSTINC:
|
||||
fprintf(OutputFile, "\tincq\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tincq\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
case OP_POSTDEC:
|
||||
fprintf(OutputFile, "\tdecq\t%s(\%%rip)\n", Entry->Name); break;
|
||||
fprintf(OutputFile, "\tdecq\t%s(\%%rip)\n", Entry->Name);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -654,18 +679,22 @@ int AsLdLocalVar(struct SymbolTableEntry* Entry, int Operation) {
|
|||
case 1:
|
||||
switch (Operation) {
|
||||
case OP_PREINC:
|
||||
fprintf(OutputFile, "\tincb\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tincb\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
case OP_PREDEC:
|
||||
fprintf(OutputFile, "\tdecb\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tdecb\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(OutputFile, "\tmovzbq\t%d(\%%rbp), %s\n", Entry->SinkOffset, Registers[Reg]);
|
||||
|
||||
switch (Operation) {
|
||||
case OP_POSTINC:
|
||||
fprintf(OutputFile, "\tincb\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tincb\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
case OP_POSTDEC:
|
||||
fprintf(OutputFile, "\tdecb\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tdecb\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -673,36 +702,44 @@ int AsLdLocalVar(struct SymbolTableEntry* Entry, int Operation) {
|
|||
case 4:
|
||||
switch (Operation) {
|
||||
case OP_PREINC:
|
||||
fprintf(OutputFile, "\tincl\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tincl\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
case OP_PREDEC:
|
||||
fprintf(OutputFile, "\tdecl\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tdecl\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(OutputFile, "\tmovslq\t%d(\%%rbp), %s\n", Entry->SinkOffset, Registers[Reg]);
|
||||
|
||||
switch (Operation) {
|
||||
case OP_POSTINC:
|
||||
fprintf(OutputFile, "\tincl\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tincl\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
case OP_POSTDEC:
|
||||
fprintf(OutputFile, "\tdecl\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tdecl\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 8:
|
||||
switch (Operation) {
|
||||
case OP_PREINC:
|
||||
fprintf(OutputFile, "\tincq\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tincq\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
case OP_PREDEC:
|
||||
fprintf(OutputFile, "\tdecq\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tdecq\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(OutputFile, "\tmovq\t%d(\%%rbp), %s\n", Entry->SinkOffset, Registers[Reg]);
|
||||
|
||||
switch (Operation) {
|
||||
case OP_POSTINC:
|
||||
fprintf(OutputFile, "\tincq\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tincq\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
case OP_POSTDEC:
|
||||
fprintf(OutputFile, "\tdecq\t%d(\%%rbp)\n", Entry->SinkOffset); break;
|
||||
fprintf(OutputFile, "\tdecq\t%d(\%%rbp)\n", Entry->SinkOffset);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -762,11 +799,14 @@ int AsDeref(int Reg, int Type) {
|
|||
printf("\tDereferencing %s\n", Registers[Reg]);
|
||||
switch (DestSize) {
|
||||
case 1:
|
||||
fprintf(OutputFile, "\tmovzbq\t(%s), %s\n", Registers[Reg], Registers[Reg]);
|
||||
fprintf(OutputFile, "\tmovzbq\t(%s), %s\n", Registers[Reg], ByteRegisters[Reg]);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(OutputFile, "\tmovslq\t(%s), %s\n", Registers[Reg], Registers[Reg]);
|
||||
fprintf(OutputFile, "\tmovslq\t(%s), %s\n", Registers[Reg], DoubleRegisters[Reg]);
|
||||
break;
|
||||
case 4:
|
||||
fprintf(OutputFile, "\tmovl\t(%s), %s\n", Registers[Reg], DoubleRegisters[Reg]);
|
||||
break;
|
||||
case 8:
|
||||
fprintf(OutputFile, "\tmovq\t(%s), %s\n", Registers[Reg], Registers[Reg]);
|
||||
break;
|
||||
|
@ -779,13 +819,16 @@ int AsDeref(int Reg, int Type) {
|
|||
|
||||
// Assemble a store-through-dereference
|
||||
int AsStrDeref(int Register1, int Register2, int Type) {
|
||||
printf("\tStoring contents of %s into %s through a dereference, type %d\n", Registers[Register1], Registers[Register2], Type);
|
||||
printf("\tStoring contents of %s into %s through a dereference, type %d\n", Registers[Register1],
|
||||
Registers[Register2], Type);
|
||||
|
||||
switch (Type) {
|
||||
case RET_CHAR:
|
||||
fprintf(OutputFile, "\tmovb\t%s, (%s)\n", ByteRegisters[Register1], Registers[Register2]);
|
||||
break;
|
||||
case RET_INT:
|
||||
fprintf(OutputFile, "\tmovl\t%s, (%s)\n", DoubleRegisters[Register1], Registers[Register2]);
|
||||
break;
|
||||
case RET_LONG:
|
||||
fprintf(OutputFile, "\tmovq\t%s, (%s)\n", Registers[Register1], Registers[Register2]);
|
||||
break;
|
||||
|
@ -812,9 +855,15 @@ void AsGlobalSymbol(struct SymbolTableEntry* Entry) {
|
|||
fprintf(OutputFile, "%s:\n", Entry->Name);
|
||||
|
||||
switch (Size) {
|
||||
case 1: fprintf(OutputFile, "\t.byte\t0\r\n", Entry->Name); break;
|
||||
case 4: fprintf(OutputFile, "\t.long\t0\r\n", Entry->Name); break;
|
||||
case 8: fprintf(OutputFile, "\t.quad\t0\r\n", Entry->Name); break;
|
||||
case 1:
|
||||
fprintf(OutputFile, "\t.byte\t0\r\n", Entry->Name);
|
||||
break;
|
||||
case 4:
|
||||
fprintf(OutputFile, "\t.long\t0\r\n", Entry->Name);
|
||||
break;
|
||||
case 8:
|
||||
fprintf(OutputFile, "\t.quad\t0\r\n", Entry->Name);
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < Size; i++)
|
||||
fprintf(OutputFile, "\t.byte\t0\n");
|
||||
|
@ -843,7 +892,7 @@ void AsCopyArgs(int Register, int Position) {
|
|||
if (Position > 4) { // Args above 4 go on the stack
|
||||
fprintf(OutputFile, "\tpushq\t%s\n", Registers[Register]);
|
||||
} else {
|
||||
fprintf(OutputFile, "\tmovq\t%s, %s\n", Registers[Register], Registers[10 - Position]);
|
||||
fprintf(OutputFile, "\tmovq\t%s, %s\n", Registers[Register], Registers[8 - Position]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
143
src/Dump.c
143
src/Dump.c
|
@ -64,54 +64,125 @@ void DumpTree(struct ASTNode* Node, int level) {
|
|||
fprintf(stdout, " ");
|
||||
|
||||
switch (Node->Operation) {
|
||||
case OP_COMP: fprintf(stdout, "\n\n"); return;
|
||||
case OP_FUNC: fprintf(stdout, "OP_FUNC %s\n", Node->Symbol->Name); return;
|
||||
case OP_ADD: fprintf(stdout, "OP_ADD\n"); return;
|
||||
case OP_SUBTRACT: fprintf(stdout, "OP_SUBTRACT\n"); return;
|
||||
case OP_MULTIPLY: fprintf(stdout, "OP_MULTIPLY\n"); return;
|
||||
case OP_DIVIDE: fprintf(stdout, "OP_DIVIDE\n"); return;
|
||||
case OP_EQUAL: fprintf(stdout, "OP_EQUAL\n"); return;
|
||||
case OP_INEQ: fprintf(stdout, "OP_INEQ\n"); return;
|
||||
case OP_LESS: fprintf(stdout, "OP_LESS\n"); return;
|
||||
case OP_GREAT: fprintf(stdout, "OP_GREAT\n"); return;
|
||||
case OP_LESSE: fprintf(stdout, "OP_LESSE\n"); return;
|
||||
case OP_GREATE: fprintf(stdout, "OP_GREATE\n"); return;
|
||||
case TERM_INTLITERAL: fprintf(stdout, "TERM_INTLITERAL %d\n", Node->IntValue); return;
|
||||
case TERM_STRLITERAL: fprintf(stdout, "TERM_STRLITERAL rval L%d\n", Node->IntValue); return;
|
||||
case OP_COMP:
|
||||
fprintf(stdout, "\n\n");
|
||||
return;
|
||||
case OP_FUNC:
|
||||
fprintf(stdout, "OP_FUNC %s\n", Node->Symbol->Name);
|
||||
return;
|
||||
case OP_ADD:
|
||||
fprintf(stdout, "OP_ADD\n");
|
||||
return;
|
||||
case OP_SUBTRACT:
|
||||
fprintf(stdout, "OP_SUBTRACT\n");
|
||||
return;
|
||||
case OP_MULTIPLY:
|
||||
fprintf(stdout, "OP_MULTIPLY\n");
|
||||
return;
|
||||
case OP_DIVIDE:
|
||||
fprintf(stdout, "OP_DIVIDE\n");
|
||||
return;
|
||||
case OP_EQUAL:
|
||||
fprintf(stdout, "OP_EQUAL\n");
|
||||
return;
|
||||
case OP_INEQ:
|
||||
fprintf(stdout, "OP_INEQ\n");
|
||||
return;
|
||||
case OP_LESS:
|
||||
fprintf(stdout, "OP_LESS\n");
|
||||
return;
|
||||
case OP_GREAT:
|
||||
fprintf(stdout, "OP_GREAT\n");
|
||||
return;
|
||||
case OP_LESSE:
|
||||
fprintf(stdout, "OP_LESSE\n");
|
||||
return;
|
||||
case OP_GREATE:
|
||||
fprintf(stdout, "OP_GREATE\n");
|
||||
return;
|
||||
case TERM_INTLITERAL:
|
||||
fprintf(stdout, "TERM_INTLITERAL %d\n", Node->IntValue);
|
||||
return;
|
||||
case TERM_STRLITERAL:
|
||||
fprintf(stdout, "TERM_STRLITERAL rval L%d\n", Node->IntValue);
|
||||
return;
|
||||
case REF_IDENT:
|
||||
if (Node->RVal)
|
||||
fprintf(stdout, "REF_IDENT rval %s\n", Node->Symbol->Name);
|
||||
else
|
||||
fprintf(stdout, "REF_IDENT %s\n", Node->Symbol->Name);
|
||||
return;
|
||||
case OP_ASSIGN: fprintf(stdout, "OP_ASSIGN\n"); return;
|
||||
case OP_WIDEN: fprintf(stdout, "OP_WIDEN\n"); return;
|
||||
case OP_RET: fprintf(stdout, "OP_RET\n"); return;
|
||||
case OP_CALL: fprintf(stdout, "OP_CALL %s\n", Node->Symbol->Name); return;
|
||||
case OP_ADDRESS: fprintf(stdout, "OP_ADDRESS %s\n", Node->Symbol->Name); return;
|
||||
case OP_ASSIGN:
|
||||
fprintf(stdout, "OP_ASSIGN\n");
|
||||
return;
|
||||
case OP_WIDEN:
|
||||
fprintf(stdout, "OP_WIDEN\n");
|
||||
return;
|
||||
case OP_RET:
|
||||
fprintf(stdout, "OP_RET\n");
|
||||
return;
|
||||
case OP_CALL:
|
||||
fprintf(stdout, "OP_CALL %s\n", Node->Symbol->Name);
|
||||
return;
|
||||
case OP_ADDRESS:
|
||||
fprintf(stdout, "OP_ADDRESS %s\n", Node->Symbol->Name);
|
||||
return;
|
||||
case OP_DEREF:
|
||||
fprintf(stdout, "OP_DEREF %s\n", Node->RVal ? "rval" : ""); return;
|
||||
case OP_SCALE: fprintf(stdout, "OP_SCALE %s\n", TypeNames(Node->Size)); return;
|
||||
fprintf(stdout, "OP_DEREF %s\n", Node->RVal ? "rval" : "");
|
||||
return;
|
||||
case OP_SCALE:
|
||||
fprintf(stdout, "OP_SCALE %s\n", TypeNames(Node->Size));
|
||||
return;
|
||||
|
||||
case OP_BOOLOR: fprintf(stdout, "OP_BOOLOR\n"); return;
|
||||
case OP_BOOLAND: fprintf(stdout, "OP_BOOLAND\n"); return;
|
||||
case OP_BITOR: fprintf(stdout, "OP_BITOR\n"); return;
|
||||
case OP_BITXOR: fprintf(stdout, "OP_BITXOR\n"); return;
|
||||
case OP_BITAND: fprintf(stdout, "OP_BITAND\n"); return;
|
||||
case OP_BOOLOR:
|
||||
fprintf(stdout, "OP_BOOLOR\n");
|
||||
return;
|
||||
case OP_BOOLAND:
|
||||
fprintf(stdout, "OP_BOOLAND\n");
|
||||
return;
|
||||
case OP_BITOR:
|
||||
fprintf(stdout, "OP_BITOR\n");
|
||||
return;
|
||||
case OP_BITXOR:
|
||||
fprintf(stdout, "OP_BITXOR\n");
|
||||
return;
|
||||
case OP_BITAND:
|
||||
fprintf(stdout, "OP_BITAND\n");
|
||||
return;
|
||||
|
||||
case OP_SHIFTL: fprintf(stdout, "OP_SHIFTL\n"); return;
|
||||
case OP_SHIFTR: fprintf(stdout, "OP_SHIFTR\n"); return;
|
||||
case OP_SHIFTL:
|
||||
fprintf(stdout, "OP_SHIFTL\n");
|
||||
return;
|
||||
case OP_SHIFTR:
|
||||
fprintf(stdout, "OP_SHIFTR\n");
|
||||
return;
|
||||
|
||||
case OP_PREINC: fprintf(stdout, "OP_PREINC\n"); return;
|
||||
case OP_PREDEC: fprintf(stdout, "OP_PREDEC\n"); return;
|
||||
case OP_POSTINC: fprintf(stdout, "OP_POSTINC\n"); return;
|
||||
case OP_POSTDEC: fprintf(stdout, "OP_POSTDEC\n"); return;
|
||||
case OP_PREINC:
|
||||
fprintf(stdout, "OP_PREINC\n");
|
||||
return;
|
||||
case OP_PREDEC:
|
||||
fprintf(stdout, "OP_PREDEC\n");
|
||||
return;
|
||||
case OP_POSTINC:
|
||||
fprintf(stdout, "OP_POSTINC\n");
|
||||
return;
|
||||
case OP_POSTDEC:
|
||||
fprintf(stdout, "OP_POSTDEC\n");
|
||||
return;
|
||||
|
||||
case OP_BITNOT: fprintf(stdout, "OP_BITNOT\n"); return;
|
||||
case OP_BOOLNOT: fprintf(stdout, "OP_BOOLNOT\n"); return;
|
||||
case OP_NEGATE: fprintf(stdout, "OP_NEGATE\n"); return;
|
||||
case OP_BITNOT:
|
||||
fprintf(stdout, "OP_BITNOT\n");
|
||||
return;
|
||||
case OP_BOOLNOT:
|
||||
fprintf(stdout, "OP_BOOLNOT\n");
|
||||
return;
|
||||
case OP_NEGATE:
|
||||
fprintf(stdout, "OP_NEGATE\n");
|
||||
return;
|
||||
|
||||
case OP_BOOLCONV: fprintf(stdout, "OP_BOOLCONV\n"); return;
|
||||
case OP_BOOLCONV:
|
||||
fprintf(stdout, "OP_BOOLCONV\n");
|
||||
return;
|
||||
|
||||
default:
|
||||
DieDecimal("Unknown Dump Operator", Node->Operation);
|
||||
|
|
39
src/Lexer.c
39
src/Lexer.c
|
@ -201,16 +201,26 @@ static int ReadCharLiteral() {
|
|||
Char = NextChar();
|
||||
if (Char == '\\') {
|
||||
switch (Char = NextChar()) {
|
||||
case 'a': return '\a';
|
||||
case 'b': return '\b';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'v': return '\v';
|
||||
case '\\': return '\\';
|
||||
case '"': return '"';
|
||||
case '\'': return '\'';
|
||||
case 'a':
|
||||
return '\a';
|
||||
case 'b':
|
||||
return '\b';
|
||||
case 'f':
|
||||
return '\f';
|
||||
case 'n':
|
||||
return '\n';
|
||||
case 'r':
|
||||
return '\r';
|
||||
case 't':
|
||||
return '\t';
|
||||
case 'v':
|
||||
return '\v';
|
||||
case '\\':
|
||||
return '\\';
|
||||
case '"':
|
||||
return '"';
|
||||
case '\'':
|
||||
return '\'';
|
||||
default:
|
||||
DieChar("Unknown Escape: ", Char);
|
||||
}
|
||||
|
@ -238,7 +248,8 @@ static int ReadStringLiteral(char* Buffer) {
|
|||
|
||||
for (int i = 0; i < TEXTLEN - 1; i++) {
|
||||
if ((Char = ReadCharLiteral()) == '"') {
|
||||
Buffer[i] = 0; return i;
|
||||
Buffer[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer[i] = Char;
|
||||
|
@ -338,7 +349,6 @@ static int ReadKeyword(char* Str) {
|
|||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -554,7 +564,8 @@ void Tokenise() {
|
|||
Token->type = LI_INT;
|
||||
break;
|
||||
|
||||
} else if(isalpha(Char) || Char == '_') { // This is what defines what a variable/function/keyword can START with.
|
||||
} else if (isalpha(Char) ||
|
||||
Char == '_') { // This is what defines what a variable/function/keyword can START with.
|
||||
ReadIdentifier(Char, CurrentIdentifier, TEXTLEN);
|
||||
|
||||
if (TokenType = ReadKeyword(CurrentIdentifier)) {
|
||||
|
@ -564,7 +575,7 @@ void Tokenise() {
|
|||
|
||||
Token->type = TY_IDENTIFIER;
|
||||
break;
|
||||
//printf("Line %d: Unrecognized symbol %s\n", CurrentIdentifier, Line);
|
||||
//printf.er("Line %d: Unrecognized symbol %s\n", CurrentIdentifier, Line);
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
/*************/
|
||||
|
||||
#include <Defs.h>
|
||||
|
||||
#define extern_
|
||||
|
||||
#include <Data.h>
|
||||
|
||||
#undef extern_
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
int TypeSizes[5] = {0, 1, 4, 8, 0}; // in BYTES
|
||||
|
@ -93,7 +96,7 @@ char* ScopeNames[] = {
|
|||
int main(int argc, char* argv[]) {
|
||||
// Option initialisers
|
||||
OptDumpTree = false;
|
||||
OptKeepAssembly = false;
|
||||
OptKeepAssembly = true;
|
||||
OptAssembleFiles = false;
|
||||
OptLinkFiles = true;
|
||||
OptVerboseOutput = false;
|
||||
|
@ -119,7 +122,7 @@ int main(int argc, char* argv[]) {
|
|||
OutputFileName = argv[++i];
|
||||
|
||||
break;
|
||||
case 'T': // Debug
|
||||
case 'T': // print Tree (debug)
|
||||
OptDumpTree = true;
|
||||
break;
|
||||
case 'c': // Compile only
|
||||
|
|
31
src/Parser.c
31
src/Parser.c
|
@ -135,7 +135,8 @@ struct ASTNode* ConstructASTLeaf(int Operation, int Type, struct SymbolTableEntr
|
|||
* @param IntValue: The integer value encoded by this Node, if applicable.
|
||||
* @return a newly constructed AST Node
|
||||
*/
|
||||
struct ASTNode* ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue) {
|
||||
struct ASTNode*
|
||||
ConstructASTBranch(int Operation, int Type, struct ASTNode* Left, struct SymbolTableEntry* Symbol, int IntValue) {
|
||||
return ConstructASTNode(Operation, Type, Left, NULL, NULL, Symbol, IntValue);
|
||||
}
|
||||
|
||||
|
@ -233,10 +234,12 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
|||
NodeType = CurrentToken.type;
|
||||
|
||||
if (NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS || NodeType == LI_COM) {
|
||||
LeftNode->RVal = 1; return LeftNode;
|
||||
LeftNode->RVal = 1;
|
||||
return LeftNode;
|
||||
}
|
||||
|
||||
while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) {
|
||||
while ((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) ||
|
||||
(IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) {
|
||||
Tokenise();
|
||||
if (CurrentToken.type == LI_RPARE)
|
||||
break;
|
||||
|
@ -257,7 +260,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
|||
LeftNode->RVal = 0;
|
||||
|
||||
RightNode = MutateType(RightNode, LeftNode->ExprType, 0);
|
||||
if(LeftNode == NULL)
|
||||
if (RightNode == NULL)
|
||||
Die("Incompatible Expression encountered in assignment");
|
||||
|
||||
// LeftNode holds the target, the target variable in this case
|
||||
|
@ -293,8 +296,9 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
|||
* equivalent to LeftNode = LeftNode
|
||||
*/
|
||||
|
||||
if(LeftTemp)
|
||||
LeftNode = LeftTemp;
|
||||
|
||||
if (LeftTemp != NULL)
|
||||
LeftNode = LeftTemp; //ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0);
|
||||
|
||||
/**
|
||||
* Same here, but there is a higher chance
|
||||
|
@ -302,20 +306,13 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
|||
* to the nature of widening types.
|
||||
*/
|
||||
|
||||
if(RightTemp)
|
||||
RightNode = RightTemp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks over, back to normal parsing.
|
||||
*/
|
||||
|
||||
if(LeftTemp != NULL)
|
||||
LeftNode = LeftTemp; //ConstructASTBranch(LeftType, RightNode->ExprType, LeftNode, 0);
|
||||
if (RightTemp != NULL)
|
||||
RightNode = RightTemp; // ConstructASTBranch(RightType, LeftNode->ExprType, RightNode, 0);
|
||||
|
||||
LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode, NULL, 0);
|
||||
}
|
||||
|
||||
LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode,
|
||||
NULL, 0);
|
||||
NodeType = CurrentToken.type;
|
||||
if (NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS) {
|
||||
LeftNode->RVal = 1;
|
||||
|
|
|
@ -146,7 +146,8 @@ struct ASTNode* AccessArray() {
|
|||
if (!TypeIsInt(RightNode->ExprType))
|
||||
Die("Array index is not integer");
|
||||
|
||||
printf("\t\tPreparing types - RightNode of type %s must be mutated to LeftNode type %s\r\n", (RightNode->ExprType), TypeNames(LeftNode->ExprType));
|
||||
printf("\t\tPreparing types - RightNode of type %s must be mutated to LeftNode type %s\r\n", (RightNode->ExprType),
|
||||
TypeNames(LeftNode->ExprType));
|
||||
RightNode = MutateType(RightNode, LeftNode->ExprType, OP_ADD);
|
||||
|
||||
LeftNode = ConstructASTNode(OP_ADD, Entry->Type, LeftNode, NULL, RightNode, NULL, 0);
|
||||
|
@ -173,7 +174,7 @@ struct ASTNode* AccessMember(bool Deref) {
|
|||
|
||||
|
||||
if ((CompositeVar = FindSymbol(CurrentIdentifier)) == NULL)
|
||||
DieMessage("Undecalred variable", CurrentIdentifier);
|
||||
DieMessage("Undeclared variable", CurrentIdentifier);
|
||||
if (Deref && CompositeVar->Type != PointerTo(DAT_STRUCT))
|
||||
DieMessage("Undeclared struct", CurrentIdentifier);
|
||||
if (!Deref && CompositeVar->Type != DAT_STRUCT)
|
||||
|
@ -191,8 +192,9 @@ struct ASTNode* AccessMember(bool Deref) {
|
|||
Tokenise();
|
||||
VerifyToken(TY_IDENTIFIER, "identifier");
|
||||
|
||||
for(Member = TypePtr->Start; Member != NULL, Member = Member->NextSymbol;) {
|
||||
printf("\tComparing struct entry %s with the wanted %s. Index %d.\r\n", Member->Name, CurrentIdentifier, Member->SinkOffset);
|
||||
for (Member = TypePtr->Start; Member != NULL; Member = Member->NextSymbol) {
|
||||
printf("\tComparing struct entry %s with the wanted %s. Index %d.\r\n", Member->Name, CurrentIdentifier,
|
||||
Member->SinkOffset);
|
||||
if (!strcmp(Member->Name, CurrentIdentifier))
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -273,7 +273,6 @@ struct ASTNode* ReturnStatement() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Handles the surrounding logic for If statements.
|
||||
*
|
||||
|
@ -438,7 +437,7 @@ struct ASTNode* ForStatement() {
|
|||
* Handles the surrounding logic for the Print statement.
|
||||
*
|
||||
* This is a legacy hold-over from the early testing, and it
|
||||
* serves merely as a wrapper around the cstdlib printf function.
|
||||
* serves merely as a wrapper around the cstdlib printf.er function.
|
||||
*
|
||||
* It does, however (//TODO), attempt to guess the type that you
|
||||
* want to print, which takes a lot of the guesswork out of printing.
|
||||
|
@ -509,7 +508,8 @@ struct ASTNode* PostfixStatement() {
|
|||
// (as functions have been called and arrays have been indexed)
|
||||
// Check that the variable is recognized..
|
||||
|
||||
if((Entry = FindSymbol(CurrentIdentifier)) == NULL || (Entry->Structure != ST_VAR && Entry->Structure != ST_FUNC)) {
|
||||
if ((Entry = FindSymbol(CurrentIdentifier)) == NULL ||
|
||||
(Entry->Structure != ST_VAR && Entry->Structure != ST_FUNC)) {
|
||||
DumpAllLists();
|
||||
DieMessage("Unknown Variable", CurrentIdentifier);
|
||||
}
|
||||
|
|
|
@ -193,7 +193,8 @@ void ClearTables() {
|
|||
*
|
||||
* @return The SymbolTableEntry* pointer that corresponds to this newly constructed node.
|
||||
*/
|
||||
struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Storage, int Length, int SinkOffset, struct SymbolTableEntry* CompositeType) {
|
||||
struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Storage, int Length, int SinkOffset,
|
||||
struct SymbolTableEntry* CompositeType) {
|
||||
|
||||
struct SymbolTableEntry* Node =
|
||||
(struct SymbolTableEntry*) malloc(sizeof(struct SymbolTableEntry));
|
||||
|
@ -206,7 +207,8 @@ struct SymbolTableEntry* AddSymbol(char* Name, int Type, int Structure, int Stor
|
|||
Node->SinkOffset = SinkOffset;
|
||||
Node->CompositeType = CompositeType;
|
||||
|
||||
printf("Adding a %s symbol of name %s, type %s to the tables.\n", ScopeNames[Node->Storage], Node->Name, TypeNames(Node->Type));
|
||||
printf("Adding a %s symbol of name %s, type %s to the tables.\n", ScopeNames[Node->Storage], Node->Name,
|
||||
TypeNames(Node->Type));
|
||||
switch (Storage) {
|
||||
case SC_GLOBAL:
|
||||
AppendSymbol(&Globals, &GlobalsEnd, Node);
|
||||
|
|
28
src/Types.c
28
src/Types.c
|
@ -44,9 +44,12 @@ int PrimitiveSize(int Type) {
|
|||
|
||||
if (TypeIsPtr(Type)) return 8;
|
||||
switch (Type) {
|
||||
case RET_CHAR: return 1;
|
||||
case RET_INT: return 4;
|
||||
case RET_LONG: return 8;
|
||||
case RET_CHAR:
|
||||
return 1;
|
||||
case RET_INT:
|
||||
return 4;
|
||||
case RET_LONG:
|
||||
return 8;
|
||||
default:
|
||||
DieBinary("Bad type in PrimitiveSize", Type);
|
||||
}
|
||||
|
@ -77,11 +80,20 @@ static char TypeBuffer[7];
|
|||
*/
|
||||
char* TypeNames(int Type) {
|
||||
switch (Type) {
|
||||
case RET_CHAR: memcpy(TypeBuffer, "Char", 4); break;
|
||||
case RET_INT: memcpy(TypeBuffer, "Int ", 4); break;
|
||||
case RET_LONG: memcpy(TypeBuffer, "Long", 4); break;
|
||||
case RET_VOID: memcpy(TypeBuffer, "Void", 4); break;
|
||||
default: break;
|
||||
case RET_CHAR:
|
||||
memcpy(TypeBuffer, "Char", 4);
|
||||
break;
|
||||
case RET_INT:
|
||||
memcpy(TypeBuffer, "Int ", 4);
|
||||
break;
|
||||
case RET_LONG:
|
||||
memcpy(TypeBuffer, "Long", 4);
|
||||
break;
|
||||
case RET_VOID:
|
||||
memcpy(TypeBuffer, "Void", 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
if (TypeIsPtr(Type)) memcpy((void*) ((size_t) TypeBuffer + 4), "Ptr", 3);
|
||||
else memcpy((void*) ((size_t) TypeBuffer + 4), " ", 3);
|
||||
|
|
6
tests/calls.c
Normal file
6
tests/calls.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("%d\n", 55);
|
||||
puts("more sup\n");
|
||||
}
|
|
@ -6,8 +6,8 @@ int :: close(int fd);
|
|||
char* textbuffer;
|
||||
|
||||
int :: main() {
|
||||
int sourcefile;
|
||||
int count;
|
||||
long sourcefile;
|
||||
long count;
|
||||
|
||||
textbuffer = " ";
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ struct a {
|
|||
int y
|
||||
};
|
||||
|
||||
int printf(char* fmt);
|
||||
int :: printf(char* fmt);
|
||||
|
||||
struct a str;
|
||||
|
||||
int main() {
|
||||
int :: main() {
|
||||
str.y = 55;
|
||||
printf("%d\n", str.y);
|
||||
return (0);
|
||||
|
|
23
tests/structbrutal.er
Normal file
23
tests/structbrutal.er
Normal file
|
@ -0,0 +1,23 @@
|
|||
int :: printf(char* fmt);
|
||||
|
||||
struct banana {
|
||||
int x,
|
||||
int y
|
||||
};
|
||||
|
||||
struct banana bread;
|
||||
struct banana* loaf;
|
||||
|
||||
int :: main() {
|
||||
bread.y = 5;
|
||||
loaf->y = 10;
|
||||
|
||||
printf("%d\n", bread.y);
|
||||
printf("%d\n", loaf->y);
|
||||
|
||||
bread.x = 7;
|
||||
|
||||
printf("%d\n", bread.y + bread.x);
|
||||
|
||||
return (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user