More comments - Pointers and Delegate

This commit is contained in:
Curle 2021-01-21 01:53:00 +00:00
parent 18b5da209d
commit 01d293f2c6
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
2 changed files with 94 additions and 4 deletions

View File

@ -7,6 +7,29 @@
#include <Data.h> #include <Data.h>
#include <errno.h> #include <errno.h>
/********************************************************************************
* The Delegate is what allows the compiler backend to be abstracted. *
* *
* It delegates the operation of compiling, assembling and linking *
* to the proper subsystems. *
* *
* As of right now (20/01/2021) it uses the GCC backend. *
* *
* Compile parses files to their AST and generates mingw PECOFF32+ assembly, *
* Assemble uses GCC-as to compile the assembly to an object file. *
* Link links the object files into an executable. *
* *
********************************************************************************/
/*
* Files inputted must have a suffix/extension (because we're on Windows right now)
* This is the way to change the suffix for when a file is converted to another.
*
* @param String: The full, current file name
* @param Suffix: The new, desired extension.
*
*/
char* Suffixate(char* String, char Suffix) { char* Suffixate(char* String, char Suffix) {
char* Pos, *NewStr; char* Pos, *NewStr;
@ -26,6 +49,14 @@ char* Suffixate(char* String, char Suffix) {
return NewStr; return NewStr;
} }
/*
* Starts most of the work to do with the Erythro compiler.
* It:
* Opens the input and output files,
* Parses the global symbols of the file, including function blocks.
* Generates the assembly representation of the source code
*/
char* Compile(char* InputFile) { char* Compile(char* InputFile) {
char* OutputName; char* OutputName;
OutputName = Suffixate(InputFile, 's'); OutputName = Suffixate(InputFile, 's');

View File

@ -7,6 +7,34 @@
#include <Defs.h> #include <Defs.h>
#include <Data.h> #include <Data.h>
/****************************************************************
* Types are enumerated by the DataTypes enum. *
* They are represented by unsigned integers, where the *
* most significant 28 bits differentiate the raw type *
* of the data being encoded. *
* However, the least significant nibble - that is, *
* the lowest 4 bits, represent the count of indirection. *
* *
* This means that a raw Integer data type, such as an i32, *
* has the DataType representation 32. *
* However, a pointer to an Integer has DataType value 32+1, *
* or 33. *
* *
* This means that the maximum valid pointer level is 16. *
* That's a: *
* ****************int *
* That ought to be enough for everyone, right? *
* *
****************************************************************/
/*
* Adds 1 to the input Type, to add a level of indirection.
* If the indirection is already at 16 levels, it aborts.
*
* @param Type: The DataType to pointerise
* @return the new pointerised DataType value.
*/
int PointerTo(int Type) { int PointerTo(int Type) {
if((Type & 0xf) == 0xf) if((Type & 0xf) == 0xf)
DieDecimal("Unrecognized type in pointerisation", Type); DieDecimal("Unrecognized type in pointerisation", Type);
@ -14,14 +42,35 @@ int PointerTo(int Type) {
return (Type + 1); return (Type + 1);
} }
/*
* Returns the underlying type behind a pointer.
* If the type is not a pointer (the lowest 4 bits are 0), it halts compliation.
*
* @param Type: The type to un-dereference
* @return the underlying Type
*/
int ValueAt(int Type) { int ValueAt(int Type) {
printf("\t\tDereferencing a %s\n", TypeNames(Type)); printf("\t\tDereferencing a %s\n", TypeNames(Type));
//TODO: this is still bullshittery!
if((Type & 0xf) == 0x0) if((Type & 0xf) == 0x0)
DieDecimal("Unrecognized type in defererencing", Type); DieDecimal("Unrecognized type in defererencing", Type);
return (Type - 1); return (Type - 1);
} }
/*
* Type declarations may be raw, they may be pointers.
* If they are pointers, we need to be able to check
* how many levels of indirection.
* However, being a pointer is optional.
*
* This can parase in just a lone type specifier, or
* any valid level of indirection therefore.
*
* @param Composite: unused
* @return the parsed DataType, with any indirection.
*
*/
int ParseOptionalPointer(struct SymbolTableEntry** Composite) { int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
int Type; int Type;
@ -61,12 +110,24 @@ int ParseOptionalPointer(struct SymbolTableEntry** Composite) {
break; break;
Type = PointerTo(Type); Type = PointerTo(Type);
Tokenise(); // Tokenise(); TODO: is this skipping pointers?
} }
return Type; return Type;
} }
/*
* Array Accesses come in the form of x[y].
*
* x must be a pointer type, and an array structure.
* y can be any binary expression.
*
* It is a wrapper around *((imax*)x + y).
*
* @return the AST Node that represents this statement.
*/
struct ASTNode* AccessArray() { struct ASTNode* AccessArray() {
struct ASTNode* LeftNode, *RightNode; struct ASTNode* LeftNode, *RightNode;
struct SymbolTableEntry* Entry; struct SymbolTableEntry* Entry;
@ -76,9 +137,7 @@ struct ASTNode* AccessArray() {
DieMessage("Accessing undeclared array", CurrentIdentifier); DieMessage("Accessing undeclared array", CurrentIdentifier);
LeftNode = ConstructASTLeaf(OP_ADDRESS, Entry->Type, Entry, 0); LeftNode = ConstructASTLeaf(OP_ADDRESS, Entry->Type, Entry, 0);
//printf("\t\tCurrent token: %s\r\n", TokenNames[CurrentToken.type]);
Tokenise(); Tokenise();
//printf("\t\tCurrent token: %s\r\n", TokenNames[CurrentToken.type]);
RightNode = ParsePrecedenceASTNode(0); RightNode = ParsePrecedenceASTNode(0);