scope refactor

pull/1/head
cosmonaut 2021-04-21 21:29:38 -07:00
parent e3fd821d8f
commit c6507fdcb7
4 changed files with 309 additions and 190 deletions

14
ast.c
View File

@ -21,6 +21,7 @@ const char* SyntaxKindString(SyntaxKind syntaxKind)
{ {
switch(syntaxKind) switch(syntaxKind)
{ {
case AccessExpression: return "AccessExpression";
case Assignment: return "Assignment"; case Assignment: return "Assignment";
case BinaryExpression: return "BinaryExpression"; case BinaryExpression: return "BinaryExpression";
case Comment: return "Comment"; case Comment: return "Comment";
@ -292,6 +293,19 @@ Node* MakeFunctionCallExpressionNode(
return node; return node;
} }
Node* MakeAccessExpressionNode(
Node *accessee,
Node *accessor
) {
Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = AccessExpression;
node->children = (Node**) malloc(sizeof(Node*) * 2);
node->childCount = 2;
node->children[0] = accessee;
node->children[1] = accessor;
return node;
}
static const char* PrimitiveTypeToString(PrimitiveType type) static const char* PrimitiveTypeToString(PrimitiveType type)
{ {
switch (type) switch (type)

5
ast.h
View File

@ -5,6 +5,7 @@
typedef enum typedef enum
{ {
AccessExpression,
Assignment, Assignment,
BinaryExpression, BinaryExpression,
Comment, Comment,
@ -148,6 +149,10 @@ Node* MakeFunctionCallExpressionNode(
Node *identifierNode, Node *identifierNode,
Node *argumentSequenceNode Node *argumentSequenceNode
); );
Node* MakeAccessExpressionNode(
Node *accessee,
Node *accessor
);
void PrintTree(Node *node, uint32_t tabCount); void PrintTree(Node *node, uint32_t tabCount);

View File

@ -14,175 +14,259 @@ extern FILE *yyin;
Stack *stack; Stack *stack;
Node *rootNode; Node *rootNode;
typedef struct StructFieldMapValue typedef struct LocalVariable
{
char *name;
LLVMValueRef pointer;
} LocalVariable;
typedef struct FunctionArgument
{ {
char *name; char *name;
LLVMValueRef value; LLVMValueRef value;
LLVMValueRef valuePointer; } FunctionArgument;
typedef struct ScopeFrame
{
LocalVariable *localVariables;
uint32_t localVariableCount;
FunctionArgument *arguments;
uint32_t argumentCount;
} ScopeFrame;
typedef struct Scope
{
ScopeFrame *scopeStack;
uint32_t scopeStackCount;
} Scope;
Scope *scope;
typedef struct StructTypeField
{
char *name;
uint32_t index; uint32_t index;
uint8_t needsWrite; } StructTypeField;
uint8_t needsRead;
} StructFieldMapValue;
typedef struct StructFieldMap typedef struct StructTypeFieldDeclaration
{ {
LLVMValueRef structPointer; LLVMTypeRef structType;
StructFieldMapValue *fields; StructTypeField *fields;
uint32_t fieldCount; uint32_t fieldCount;
} StructFieldMap;
StructFieldMap *structFieldMaps; } StructTypeFieldDeclaration;
uint32_t structFieldMapCount;
static void AddStruct(LLVMValueRef wStructPointer) StructTypeFieldDeclaration *structTypeFieldDeclarations;
uint32_t structTypeFieldDeclarationCount;
static Scope* CreateScope()
{ {
structFieldMaps = realloc(structFieldMaps, sizeof(StructFieldMap) * (structFieldMapCount + 1)); Scope *scope = malloc(sizeof(Scope));
structFieldMaps[structFieldMapCount].structPointer = wStructPointer;
structFieldMaps[structFieldMapCount].fields = NULL; scope->scopeStack = malloc(sizeof(ScopeFrame));
structFieldMaps[structFieldMapCount].fieldCount = 0; scope->scopeStack[0].argumentCount = 0;
structFieldMapCount += 1; scope->scopeStack[0].arguments = NULL;
scope->scopeStack[0].localVariableCount = 0;
scope->scopeStack[0].localVariables = NULL;
scope->scopeStackCount = 1;
return scope;
} }
static void AddStructFieldName(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name, uint32_t index) static void PushScopeFrame(Scope *scope)
{ {
uint32_t i, fieldCount; uint32_t index = scope->scopeStackCount;
scope->scopeStack = realloc(scope->scopeStack, sizeof(ScopeFrame) * (scope->scopeStackCount + 1));
scope->scopeStack[index].argumentCount = 0;
scope->scopeStack[index].arguments = NULL;
scope->scopeStack[index].localVariableCount = 0;
scope->scopeStack[index].localVariables = NULL;
for (i = 0; i < structFieldMapCount; i += 1) scope->scopeStackCount += 1;
{
if (structFieldMaps[i].structPointer == wStructPointer)
{
fieldCount = structFieldMaps[i].fieldCount;
structFieldMaps[i].fields = realloc(structFieldMaps[i].fields, sizeof(StructFieldMapValue) * (fieldCount + 1));
structFieldMaps[i].fields[fieldCount].name = strdup(name);
structFieldMaps[i].fields[fieldCount].value = NULL;
structFieldMaps[i].fields[fieldCount].valuePointer = NULL;
structFieldMaps[i].fields[fieldCount].index = index;
structFieldMaps[i].fields[fieldCount].needsWrite = 0;
structFieldMaps[i].fields[fieldCount].needsRead = 1;
structFieldMaps[i].fieldCount += 1;
break;
}
}
} }
static LLVMValueRef CheckStructFieldAndLoad(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name) static void PopScopeFrame(Scope *scope)
{ {
uint32_t i, j; uint32_t i;
uint32_t index = scope->scopeStackCount - 1;
for (i = 0; i < structFieldMapCount; i += 1) if (scope->scopeStack[index].arguments != NULL)
{ {
if (structFieldMaps[i].structPointer == wStructPointer) for (i = 0; i < scope->scopeStack[index].argumentCount; i += 1)
{ {
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) free(scope->scopeStack[index].arguments[i].name);
}
free(scope->scopeStack[index].arguments);
}
if (scope->scopeStack[index].localVariables != NULL)
{ {
if (strcmp(structFieldMaps[i].fields[j].name, name) == 0) for (i = 0; i < scope->scopeStack[index].localVariableCount; i += 1)
{ {
if (structFieldMaps[i].fields[j].needsRead) free(scope->scopeStack[index].localVariables[i].name);
}
free(scope->scopeStack[index].localVariables);
}
scope->scopeStackCount -= 1;
scope->scopeStack = realloc(scope->scopeStack, sizeof(ScopeFrame) * scope->scopeStackCount);
}
static void AddLocalVariable(Scope *scope, LLVMValueRef pointer, char *name)
{
ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1];
uint32_t index = scopeFrame->localVariableCount;
scopeFrame->localVariables = realloc(scopeFrame->localVariables, sizeof(LocalVariable) * (scopeFrame->localVariableCount + 1));
scopeFrame->localVariables[index].name = strdup(name);
scopeFrame->localVariables[index].pointer = pointer;
scopeFrame->localVariableCount += 1;
}
static void AddFunctionArgument(Scope *scope, LLVMValueRef value, char *name)
{
ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1];
uint32_t index = scopeFrame->argumentCount;
scopeFrame->arguments = realloc(scopeFrame->arguments, sizeof(FunctionArgument) * (scopeFrame->argumentCount + 1));
scopeFrame->arguments[index].name = strdup(name);
scopeFrame->arguments[index].value = value;
scopeFrame->argumentCount += 1;
}
static LLVMValueRef FindStructFieldPointer(LLVMBuilderRef builder, LLVMValueRef structPointer, char *name)
{
int32_t i, j;
LLVMTypeRef structType = LLVMTypeOf(structPointer);
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
{
if (structTypeFieldDeclarations[i].structType == structType)
{
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
{
if (strcmp(structTypeFieldDeclarations[i].fields[j].name, name) == 0)
{ {
char *ptrName = strdup(name); char *ptrName = strdup(name);
strcat(ptrName, "_ptr"); strcat(ptrName, "_ptr");
LLVMValueRef elementPointer = LLVMBuildStructGEP( return LLVMBuildStructGEP(
builder, builder,
wStructPointer, structPointer,
structFieldMaps[i].fields[j].index, structTypeFieldDeclarations[i].fields[j].index,
ptrName ptrName
); );
free(ptrName); free(ptrName);
structFieldMaps[i].fields[j].value = LLVMBuildLoad(builder, elementPointer, name);
structFieldMaps[i].fields[j].valuePointer = elementPointer;
structFieldMaps[i].fields[j].needsRead = 0;
}
return structFieldMaps[i].fields[j].value;
} }
} }
} }
} }
printf("Failed to find struct field pointer!");
return NULL; return NULL;
} }
static void MarkStructFieldForWrite(LLVMValueRef wStructPointer, LLVMValueRef value) static LLVMValueRef FindVariablePointer(char *name)
{ {
uint32_t i, j; int32_t i, j;
for (i = 0; i < structFieldMapCount; i += 1) for (i = scope->scopeStackCount - 1; i >= 0; i -= 1)
{ {
if (structFieldMaps[i].structPointer == wStructPointer) for (j = 0; j < scope->scopeStack[i].localVariableCount; j += 1)
{ {
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) if (strcmp(scope->scopeStack[i].localVariables[j].name, name) == 0)
{ {
if (structFieldMaps[i].fields[j].value == value) return scope->scopeStack[i].localVariables[j].pointer;
{
structFieldMaps[i].fields[j].needsWrite = 1;
break;
}
}
}
}
}
static LLVMValueRef GetStructFieldPointer(LLVMValueRef wStructPointer, LLVMValueRef value)
{
uint32_t i, j;
for (i = 0; i < structFieldMapCount; i += 1)
{
if (structFieldMaps[i].structPointer == wStructPointer)
{
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1)
{
if (structFieldMaps[i].fields[j].value == value)
{
return structFieldMaps[i].fields[j].valuePointer;
}
} }
} }
} }
printf("Failed to find variable pointer!");
return NULL; return NULL;
} }
static void RemoveStruct(LLVMBuilderRef builder, LLVMValueRef wStructPointer) static LLVMValueRef FindVariableValue(LLVMBuilderRef builder, char *name)
{ {
int32_t i, j;
for (i = scope->scopeStackCount - 1; i >= 0; i -= 1)
{
for (j = 0; j < scope->scopeStack[i].argumentCount; j += 1)
{
if (strcmp(scope->scopeStack[i].arguments[j].name, name) == 0)
{
return scope->scopeStack[i].arguments[j].value;
}
}
for (j = 0; j < scope->scopeStack[i].localVariableCount; j += 1)
{
if (strcmp(scope->scopeStack[i].localVariables[j].name, name) == 0)
{
return LLVMBuildLoad(builder, scope->scopeStack[i].localVariables[j].pointer, name);
}
}
}
printf("Failed to find variable value!");
return NULL;
}
static void AddStructDeclaration(
LLVMTypeRef wStructType,
Node **fieldDeclarations,
uint32_t fieldDeclarationCount
) {
uint32_t i;
uint32_t index = structTypeFieldDeclarationCount;
structTypeFieldDeclarations = realloc(structTypeFieldDeclarations, sizeof(StructTypeFieldDeclaration) * (structTypeFieldDeclarationCount + 1));
structTypeFieldDeclarations[index].structType = wStructType;
structTypeFieldDeclarations[index].fields = NULL;
structTypeFieldDeclarations[index].fieldCount = 0;
for (i = 0; i < fieldDeclarationCount; i += 1)
{
structTypeFieldDeclarations[index].fields = realloc(structTypeFieldDeclarations[index].fields, sizeof(StructTypeField) * (structTypeFieldDeclarations[index].fieldCount + 1));
structTypeFieldDeclarations[index].fields[i].name = strdup(fieldDeclarations[i]->children[1]->value.string);
structTypeFieldDeclarations[index].fields[i].index = i;
structTypeFieldDeclarations[index].fieldCount += 1;
}
structTypeFieldDeclarationCount += 1;
}
static void AddStructVariables(
LLVMBuilderRef builder,
LLVMValueRef structPointer
) {
uint32_t i, j; uint32_t i, j;
for (i = 0; i < structFieldMapCount; i += 1) for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
{ {
if (structFieldMaps[i].structPointer == wStructPointer) if (structTypeFieldDeclarations[i].structType == LLVMTypeOf(structPointer))
{ {
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
{ {
if (structFieldMaps[i].fields[j].needsWrite) LLVMValueRef elementPointer = LLVMBuildStructGEP(
{
LLVMBuildStore(
builder, builder,
structFieldMaps[i].fields[j].value, structPointer,
structFieldMaps[i].fields[j].valuePointer structTypeFieldDeclarations[i].fields[j].index,
structTypeFieldDeclarations[i].fields[j].name
);
AddLocalVariable(
scope,
elementPointer,
structTypeFieldDeclarations[i].fields[j].name
); );
} }
} }
free(structFieldMaps[i].fields);
structFieldMaps[i].fields = NULL;
structFieldMaps[i].fieldCount = 0;
break;
} }
} }
}
typedef struct IdentifierMapValue
{
char *name;
LLVMValueRef value;
} IdentifierMapValue;
IdentifierMapValue *namedVariables;
uint32_t namedVariableCount;
static LLVMValueRef CompileExpression( static LLVMValueRef CompileExpression(
LLVMValueRef wStructValue, LLVMValueRef wStructValue,
@ -191,43 +275,6 @@ static LLVMValueRef CompileExpression(
Node *binaryExpression Node *binaryExpression
); );
static void AddNamedVariable(char *name, LLVMValueRef variable)
{
IdentifierMapValue mapValue;
mapValue.name = name;
mapValue.value = variable;
namedVariables = realloc(namedVariables, sizeof(IdentifierMapValue) * (namedVariableCount + 1));
namedVariables[namedVariableCount] = mapValue;
namedVariableCount += 1;
}
static LLVMValueRef FindVariableByName(LLVMBuilderRef builder, LLVMValueRef wStructValue, char *name)
{
uint32_t i, j;
LLVMValueRef searchResult;
/* first, search scoped vars */
for (i = 0; i < namedVariableCount; i += 1)
{
if (strcmp(namedVariables[i].name, name) == 0)
{
return namedVariables[i].value;
}
}
/* if none exist, search struct vars */
searchResult = CheckStructFieldAndLoad(builder, wStructValue, name);
if (searchResult == NULL)
{
fprintf(stderr, "Identifier not found!");
}
return searchResult;
}
typedef struct CustomTypeMap typedef struct CustomTypeMap
{ {
LLVMTypeRef type; LLVMTypeRef type;
@ -312,6 +359,7 @@ static LLVMValueRef CompileBinaryExpression(
return NULL; return NULL;
} }
/* FIXME THIS IS ALL BROKEN */
static LLVMValueRef CompileFunctionCallExpression( static LLVMValueRef CompileFunctionCallExpression(
LLVMValueRef wStructValue, LLVMValueRef wStructValue,
LLVMBuilderRef builder, LLVMBuilderRef builder,
@ -327,7 +375,33 @@ static LLVMValueRef CompileFunctionCallExpression(
args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]); args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]);
} }
return LLVMBuildCall(builder, FindVariableByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp"); //return LLVMBuildCall(builder, FindVariableValueByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp");
return NULL;
}
static LLVMValueRef CompileAccessExpressionForStore(
LLVMBuilderRef builder,
LLVMValueRef wStructValue,
LLVMValueRef function,
Node *expression
) {
Node *accessee = expression->children[0];
Node *accessor = expression->children[1];
LLVMValueRef accesseeValue = FindVariablePointer(accessee->value.string);
return FindStructFieldPointer(builder, accesseeValue, accessor->value.string);
}
static LLVMValueRef CompileAccessExpression(
LLVMBuilderRef builder,
LLVMValueRef wStructValue,
LLVMValueRef function,
Node *expression
) {
Node *accessee = expression->children[0];
Node *accessor = expression->children[1];
LLVMValueRef accesseeValue = FindVariablePointer(accessee->value.string);
LLVMValueRef access = FindStructFieldPointer(builder, accesseeValue, accessor->value.string);
return LLVMBuildLoad(builder, access, accessor->value.string);
} }
static LLVMValueRef CompileExpression( static LLVMValueRef CompileExpression(
@ -340,6 +414,9 @@ static LLVMValueRef CompileExpression(
switch (expression->syntaxKind) switch (expression->syntaxKind)
{ {
case AccessExpression:
return CompileAccessExpression(builder, wStructValue, function, expression);
case BinaryExpression: case BinaryExpression:
return CompileBinaryExpression(wStructValue, builder, function, expression); return CompileBinaryExpression(wStructValue, builder, function, expression);
@ -347,7 +424,7 @@ static LLVMValueRef CompileExpression(
return CompileFunctionCallExpression(wStructValue, builder, function, expression); return CompileFunctionCallExpression(wStructValue, builder, function, expression);
case Identifier: case Identifier:
return FindVariableByName(builder, wStructValue, expression->value.string); return FindVariableValue(builder, expression->value.string);
case Number: case Number:
return CompileNumber(expression); return CompileNumber(expression);
@ -357,9 +434,12 @@ static LLVMValueRef CompileExpression(
return NULL; return NULL;
} }
/* FIXME: we need a scope structure */
static void CompileReturn(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement) static void CompileReturn(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
{ {
LLVMBuildRet(builder, CompileExpression(wStructValue, builder, function, returnStatemement->children[0])); uint32_t i, j;
LLVMValueRef expression = CompileExpression(wStructValue, builder, function, returnStatemement->children[0]);
LLVMBuildRet(builder, expression);
} }
static void CompileReturnVoid(LLVMBuilderRef builder) static void CompileReturnVoid(LLVMBuilderRef builder)
@ -371,9 +451,17 @@ static void CompileAssignment(LLVMValueRef wStructValue, LLVMBuilderRef builder,
{ {
LLVMValueRef fieldPointer; LLVMValueRef fieldPointer;
LLVMValueRef result = CompileExpression(wStructValue, builder, function, assignmentStatement->children[1]); LLVMValueRef result = CompileExpression(wStructValue, builder, function, assignmentStatement->children[1]);
LLVMValueRef identifier = CompileExpression(wStructValue, builder, function, assignmentStatement->children[0]); LLVMValueRef identifier;
if (assignmentStatement->children[0]->syntaxKind == AccessExpression)
{
identifier = CompileAccessExpressionForStore(builder, wStructValue, function, assignmentStatement->children[0]);
}
else if (assignmentStatement->children[0]->syntaxKind == Identifier)
{
identifier = FindVariablePointer(assignmentStatement->children[0]->value.string);
}
MarkStructFieldForWrite(wStructValue, identifier); LLVMBuildStore(builder, result, identifier);
} }
static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration) static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration)
@ -390,7 +478,7 @@ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *var
variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), variableName); variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), variableName);
} }
AddNamedVariable(variableName, variable); AddLocalVariable(scope, variable, variableName);
} }
static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement) static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement)
@ -432,6 +520,8 @@ static void CompileFunction(
uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */ uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */
LLVMTypeRef paramTypes[argumentCount]; LLVMTypeRef paramTypes[argumentCount];
PushScopeFrame(scope);
paramTypes[0] = wStructPointerType; paramTypes[0] = wStructPointerType;
for (i = 0; i < functionSignature->children[2]->childCount; i += 1) for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
@ -443,25 +533,19 @@ static void CompileFunction(
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, argumentCount, 0); LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, argumentCount, 0);
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType); LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef wStructPointer = LLVMGetParam(function, 0); LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
AddStructVariables(builder, wStructPointer);
for (i = 0; i < functionSignature->children[2]->childCount; i += 1) for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
{ {
LLVMValueRef argument = LLVMGetParam(function, i + 1); LLVMValueRef argument = LLVMGetParam(function, i + 1);
AddNamedVariable(functionSignature->children[2]->children[i]->children[1]->value.string, argument); LLVMValueRef argumentCopy = LLVMBuildAlloca(builder, LLVMTypeOf(argument), functionSignature->children[2]->children[i]->children[1]->value.string);
} AddLocalVariable(scope, argumentCopy, functionSignature->children[2]->children[i]->children[1]->value.string);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
/* FIXME: replace this with a scope abstraction */
AddStruct(wStructPointer);
for (i = 0; i < fieldDeclarationCount; i += 1)
{
AddStructFieldName(builder, wStructPointer, fieldDeclarations[i]->children[1]->value.string, i);
} }
for (i = 0; i < functionBody->childCount; i += 1) for (i = 0; i < functionBody->childCount; i += 1)
@ -469,8 +553,6 @@ static void CompileFunction(
hasReturn |= CompileStatement(wStructPointer, builder, function, functionBody->children[i]); hasReturn |= CompileStatement(wStructPointer, builder, function, functionBody->children[i]);
} }
RemoveStruct(builder, wStructPointer);
if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn) if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn)
{ {
LLVMBuildRetVoid(builder); LLVMBuildRetVoid(builder);
@ -479,6 +561,8 @@ static void CompileFunction(
{ {
fprintf(stderr, "Return statement not provided!"); fprintf(stderr, "Return statement not provided!");
} }
PopScopeFrame(scope);
} }
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node) static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
@ -491,6 +575,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
Node *currentDeclarationNode; Node *currentDeclarationNode;
Node *fieldDeclarations[declarationCount]; Node *fieldDeclarations[declarationCount];
PushScopeFrame(scope);
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string); LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string);
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */ LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
@ -510,6 +596,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
} }
LLVMStructSetBody(wStruct, types, fieldCount, packed); LLVMStructSetBody(wStruct, types, fieldCount, packed);
AddStructDeclaration(wStructPointerType, fieldDeclarations, fieldCount);
RegisterCustomType(wStruct, node->children[0]->value.string);
/* now we can wire up the functions */ /* now we can wire up the functions */
for (i = 0; i < declarationCount; i += 1) for (i = 0; i < declarationCount; i += 1)
@ -524,7 +612,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
} }
} }
RegisterCustomType(wStruct, node->children[0]->value.string); PopScopeFrame(scope);
} }
static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node) static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
@ -552,11 +640,10 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
namedVariables = NULL; scope = CreateScope();
namedVariableCount = 0;
structFieldMaps = NULL; structTypeFieldDeclarations = NULL;
structFieldMapCount = 0; structTypeFieldDeclarationCount = 0;
customTypes = NULL; customTypes = NULL;
customTypeCount = 0; customTypeCount = 0;

View File

@ -115,8 +115,16 @@ Identifier : ID
$$ = MakeIdentifierNode(yytext); $$ = MakeIdentifierNode(yytext);
} }
PrimaryExpression : Identifier AccessExpression : Identifier POINT AccessExpression
| NUMBER {
$$ = MakeAccessExpressionNode($1, $3);
}
| Identifier
{
$$ = $1;
}
PrimaryExpression : NUMBER
{ {
$$ = MakeNumberNode(yytext); $$ = MakeNumberNode(yytext);
} }
@ -129,6 +137,7 @@ PrimaryExpression : Identifier
$$ = $2; $$ = $2;
} }
| FunctionCallExpression | FunctionCallExpression
| AccessExpression
; ;
UnaryExpression : BANG Expression UnaryExpression : BANG Expression
@ -164,6 +173,10 @@ VariableDeclaration : Type Identifier
} }
AssignmentStatement : VariableDeclaration EQUAL Expression AssignmentStatement : VariableDeclaration EQUAL Expression
{
$$ = MakeAssignmentNode($1, $3);
}
| AccessExpression EQUAL Expression
{ {
$$ = MakeAssignmentNode($1, $3); $$ = MakeAssignmentNode($1, $3);
} }