major set building
Co-authored-by: SirTalksalot75 <SirTalksalot75@users.noreply.github.com> Co-authored-by: servostar <Servostar@users.noreply.github.com>
This commit is contained in:
parent
4d33c81c3f
commit
d0b1d367d5
|
@ -3,6 +3,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <io/files.h>
|
#include <io/files.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/col.h>
|
#include <sys/col.h>
|
||||||
|
@ -79,7 +81,7 @@ static void custom_fgets(char *buffer, size_t n, FILE *stream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message) {
|
void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message, ...) {
|
||||||
assert(file->handle != NULL);
|
assert(file->handle != NULL);
|
||||||
assert(location != NULL);
|
assert(location != NULL);
|
||||||
assert(message != NULL);
|
assert(message != NULL);
|
||||||
|
@ -117,8 +119,16 @@ void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, c
|
||||||
|
|
||||||
const char *absolute_path = get_absolute_path(file->path);
|
const char *absolute_path = get_absolute_path(file->path);
|
||||||
|
|
||||||
printf("%s%s:%ld:%s %s%s:%s %s\n", BOLD, absolute_path, location->line_start, RESET, accent_color, kind_text, RESET,
|
printf("%s%s:%ld:%s %s%s:%s ", BOLD, absolute_path, location->line_start, RESET, accent_color, kind_text, RESET);
|
||||||
message);
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
vprintf(message, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
free((void *) absolute_path);
|
free((void *) absolute_path);
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ TokenLocation empty_location(void);
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
[[gnu::nonnull(1), gnu::nonnull(2)]]
|
[[gnu::nonnull(1), gnu::nonnull(2)]]
|
||||||
void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message);
|
void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message, ...);
|
||||||
|
|
||||||
[[gnu::nonnull(2)]]
|
[[gnu::nonnull(2)]]
|
||||||
/**
|
/**
|
||||||
|
|
468
src/set/set.c
468
src/set/set.c
|
@ -1,5 +1,5 @@
|
||||||
#include "io/files.h"
|
#include <io/files.h>
|
||||||
#include "yacc/parser.tab.h"
|
#include <yacc/parser.tab.h>
|
||||||
#include <complex.h>
|
#include <complex.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
|
@ -11,9 +11,17 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <set/set.h>
|
#include <set/set.h>
|
||||||
|
|
||||||
GHashTable *declaredComposites = NULL;//pointer to composites with names,
|
//
|
||||||
GHashTable *declaredBoxes = NULL;//pointer to typeboxes
|
// .--.
|
||||||
GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var
|
// | '----------. .
|
||||||
|
// > | ~ ~ ~ ~ ~ .o O
|
||||||
|
// | .----------' o
|
||||||
|
// `--'
|
||||||
|
//
|
||||||
|
|
||||||
|
static GHashTable *declaredComposites = NULL;//pointer to composites with names
|
||||||
|
static GHashTable *declaredBoxes = NULL;//pointer to typeboxes
|
||||||
|
static GArray *Scope = NULL;//list of hashtables. last Hashtable is current depth of program. hashtable key: ident, value: Variable* to var
|
||||||
|
|
||||||
const Type ShortShortUnsingedIntType = {
|
const Type ShortShortUnsingedIntType = {
|
||||||
.kind = TypeKindComposite,
|
.kind = TypeKindComposite,
|
||||||
|
@ -264,9 +272,15 @@ int get_type_impl(AST_NODE_PTR currentNode, Type** type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageQualifier Qualifier_from_string(const char *str) {
|
StorageQualifier Qualifier_from_string(const char *str) {
|
||||||
if (!strncmp(str, "local", 5)) return Local;
|
assert(str != NULL);
|
||||||
if (!strncmp(str, "static", 6)) return Static;
|
|
||||||
if (!strncmp(str, "global", 6)) return Global;
|
if (strcmp(str, "local") == 0)
|
||||||
|
return Local;
|
||||||
|
if (strcmp(str, "static") == 0)
|
||||||
|
return Static;
|
||||||
|
if (strcmp(str, "global") == 0)
|
||||||
|
return Global;
|
||||||
|
|
||||||
PANIC("Provided string is not a storagequalifier: %s", str);
|
PANIC("Provided string is not a storagequalifier: %s", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,42 +330,99 @@ int createDecl(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expression* createExpression(AST_NODE_PTR currentNode);
|
||||||
|
|
||||||
int createDef(AST_NODE_PTR currentNode, GArray** variables) {
|
int createDef(AST_NODE_PTR currentNode, GArray** variables) {
|
||||||
assert(variables != NULL);
|
assert(variables != NULL);
|
||||||
assert(currentNode != NULL);
|
assert(currentNode != NULL);
|
||||||
|
assert(currentNode->kind == AST_Def);
|
||||||
|
|
||||||
DEBUG("create definition");
|
DEBUG("create definition");
|
||||||
|
|
||||||
AST_NODE_PTR declaration = currentNode->children[currentNode->child_count - 1];
|
AST_NODE_PTR declaration = currentNode->children[0];
|
||||||
|
AST_NODE_PTR expression = currentNode->children[1];
|
||||||
|
AST_NODE_PTR ident_list = currentNode->children[0]->children[currentNode->child_count - 1];
|
||||||
|
|
||||||
*variables = g_array_new(FALSE, FALSE, sizeof(Variable*));
|
*variables = g_array_new(FALSE, FALSE, sizeof(Variable*));
|
||||||
|
|
||||||
|
VariableDeclaration decl;
|
||||||
VariableDefiniton def;
|
VariableDefiniton def;
|
||||||
def.nodePtr = currentNode;
|
def.nodePtr = currentNode;
|
||||||
|
|
||||||
Variable* variable = malloc(sizeof(Variable));
|
|
||||||
variable->kind = VariableKindDefinition;
|
|
||||||
variable->nodePtr = currentNode;
|
|
||||||
variable->name = declaration->children[1]->value;
|
|
||||||
variable->impl.definiton= def;
|
|
||||||
g_array_append_val(*variables, variable);
|
|
||||||
|
|
||||||
int status = SEMANTIC_OK;
|
int status = SEMANTIC_OK;
|
||||||
|
|
||||||
DEBUG("Child Count: %i", currentNode->child_count);
|
DEBUG("Child Count: %i", declaration->child_count);
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++){
|
for (size_t i = 0; i < declaration->children[i]->child_count; i++){
|
||||||
|
switch(declaration->children[i]->kind) {
|
||||||
switch(currentNode->children[i]->kind) {
|
case AST_Storage:
|
||||||
case AST_Decl:
|
DEBUG("fill Qualifier");
|
||||||
|
decl.qualifier = Qualifier_from_string(currentNode->children[i]->value);
|
||||||
|
break;
|
||||||
|
case AST_Type:
|
||||||
|
DEBUG("fill Type");
|
||||||
|
status = get_type_impl(currentNode->children[i], &decl.type);
|
||||||
|
break;
|
||||||
|
case AST_IdentList:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("invalid node type: %ld", currentNode->children[i]->kind);
|
PANIC("invalid node type: %ld", currentNode->children[i]->kind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def.declaration = decl;
|
||||||
|
Expression * name = createExpression(expression);
|
||||||
|
if (name == NULL){
|
||||||
|
status = SEMANTIC_OK;
|
||||||
|
}
|
||||||
|
def.initializer = name;
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i = 0; i < ident_list->child_count; i++) {
|
||||||
|
Variable* variable = malloc(sizeof(Variable));
|
||||||
|
|
||||||
|
variable->kind = VariableKindDefinition;
|
||||||
|
variable->nodePtr = currentNode;
|
||||||
|
variable->name = ident_list->children[i]->value;
|
||||||
|
variable->impl.definiton = def;
|
||||||
|
g_array_append_val(*variables, variable);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//int: a,b,c = 5
|
||||||
|
//
|
||||||
|
//GArray.data:
|
||||||
|
// 1. Variable
|
||||||
|
// kind = VariableKindDefinition;
|
||||||
|
// name = a;
|
||||||
|
// impl.definition:
|
||||||
|
// initilizer:
|
||||||
|
// createExpression(...)
|
||||||
|
// decl:
|
||||||
|
// qulifier:
|
||||||
|
// type:
|
||||||
|
// pointer
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 2. Variable
|
||||||
|
// kind = VariableKindDefinition;
|
||||||
|
// name = b;
|
||||||
|
// impl.definition:
|
||||||
|
// initilizer: 5
|
||||||
|
// decl:
|
||||||
|
// qulifier:
|
||||||
|
// type:
|
||||||
|
// pointer
|
||||||
|
// .
|
||||||
|
// .
|
||||||
|
// .
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int getVariableFromScope(const char* name, Variable** variable) {
|
int getVariableFromScope(const char* name, Variable** variable) {
|
||||||
assert(name != NULL);
|
assert(name != NULL);
|
||||||
assert(variable != NULL);
|
assert(variable != NULL);
|
||||||
|
@ -413,17 +484,23 @@ TypeValue createTypeValue(AST_NODE_PTR currentNode){
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void* clone(int size, void* ptr) {
|
||||||
|
char* data = malloc(size);
|
||||||
|
memcpy(data, ptr, size);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CLONE(x) clone(sizeof(x), (void*)&(x))
|
||||||
|
|
||||||
TypeValue createString(AST_NODE_PTR currentNode) {
|
TypeValue createString(AST_NODE_PTR currentNode) {
|
||||||
TypeValue value;
|
TypeValue value;
|
||||||
Type *type = (Type*) &StringLiteralType;
|
Type *type = CLONE(StringLiteralType);
|
||||||
value.type = type;
|
value.type = type;
|
||||||
value.nodePtr = currentNode;
|
value.nodePtr = currentNode;
|
||||||
value.value = currentNode->value;
|
value.value = currentNode->value;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* createExpression(AST_NODE_PTR currentNode);
|
|
||||||
|
|
||||||
Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) {
|
Type* createTypeFromOperands(Type* LeftOperandType, Type* RightOperandType, AST_NODE_PTR currentNode) {
|
||||||
Type *result = malloc(sizeof(Type));
|
Type *result = malloc(sizeof(Type));
|
||||||
result->nodePtr = currentNode;
|
result->nodePtr = currentNode;
|
||||||
|
@ -650,7 +727,7 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod
|
||||||
//fill Operand
|
//fill Operand
|
||||||
Expression* expression = createExpression(currentNode->children[0]);
|
Expression* expression = createExpression(currentNode->children[0]);
|
||||||
if(NULL == expression){
|
if(NULL == expression){
|
||||||
return 1;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
g_array_append_val(ParentExpression->impl.operation.operands , expression);
|
g_array_append_val(ParentExpression->impl.operation.operands , expression);
|
||||||
|
|
||||||
|
@ -660,35 +737,38 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod
|
||||||
|
|
||||||
Type* result = malloc(sizeof(Type));
|
Type* result = malloc(sizeof(Type));
|
||||||
result->nodePtr = currentNode;
|
result->nodePtr = currentNode;
|
||||||
|
|
||||||
if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) {
|
if (Operand->kind == TypeKindBox || Operand->kind == TypeKindReference) {
|
||||||
return 1;
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Operand->kind == TypeKindPrimitive) {
|
if (Operand->kind == TypeKindPrimitive) {
|
||||||
if (Operand->impl.primitive == Float) {
|
if (Operand->impl.primitive == Float) {
|
||||||
return 1;
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
result->kind = Operand->kind;
|
result->kind = Operand->kind;
|
||||||
result->impl = Operand->impl;
|
result->impl = Operand->impl;
|
||||||
|
|
||||||
} else if(Operand->kind == TypeKindComposite) {
|
} else if(Operand->kind == TypeKindComposite) {
|
||||||
if (Operand->impl.composite.primitive == Float) {
|
if (Operand->impl.composite.primitive == Float) {
|
||||||
return 1;
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand must be a variant of primitive type int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
result->kind = Operand->kind;
|
result->kind = Operand->kind;
|
||||||
result->impl = Operand->impl;
|
result->impl = Operand->impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParentExpression->result = result;
|
ParentExpression->result = result;
|
||||||
return 0;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isScaleEqual(double leftScale, double rightScale) {
|
bool isScaleEqual(double leftScale, double rightScale) {
|
||||||
int leftIntScale =(int)(leftScale *4);
|
int leftIntScale = (int) (leftScale * BASE_BYTES);
|
||||||
int rightIntScale =(int)(rightScale *4);
|
int rightIntScale = (int) (rightScale * BASE_BYTES);
|
||||||
|
|
||||||
if (leftIntScale == rightIntScale){
|
return leftIntScale == rightIntScale;
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) {
|
int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode) {
|
||||||
|
@ -699,70 +779,110 @@ int createBitOperation(Expression* ParentExpression, AST_NODE_PTR currentNode){
|
||||||
// fill Operands
|
// fill Operands
|
||||||
for (size_t i = 0; i < currentNode->child_count; i++) {
|
for (size_t i = 0; i < currentNode->child_count; i++) {
|
||||||
Expression* expression = createExpression(currentNode->children[i]);
|
Expression* expression = createExpression(currentNode->children[i]);
|
||||||
|
|
||||||
if(NULL == expression) {
|
if(NULL == expression) {
|
||||||
return 1;
|
return SEMANTIC_ERROR;
|
||||||
}
|
|
||||||
g_array_append_val(ParentExpression->impl.operation.operands , expression);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_array_append_val(ParentExpression->impl.operation.operands , expression);
|
||||||
|
}
|
||||||
|
|
||||||
switch (currentNode->kind) {
|
switch (currentNode->kind) {
|
||||||
case AST_BitAnd:
|
case AST_BitAnd:
|
||||||
ParentExpression->impl.operation.impl.bitwise = BitwiseAnd;
|
ParentExpression->impl.operation.impl.bitwise = BitwiseAnd;
|
||||||
|
break;
|
||||||
case AST_BitOr:
|
case AST_BitOr:
|
||||||
ParentExpression->impl.operation.impl.bitwise = BitwiseOr;
|
ParentExpression->impl.operation.impl.bitwise = BitwiseOr;
|
||||||
|
break;
|
||||||
case AST_BitXor:
|
case AST_BitXor:
|
||||||
ParentExpression->impl.operation.impl.bitwise = BitwiseXor;
|
ParentExpression->impl.operation.impl.bitwise = BitwiseXor;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("Current node is not an bitwise operater");
|
PANIC("Current node is not an bitwise operater");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type *result = malloc(sizeof(Type));
|
Type *result = malloc(sizeof(Type));
|
||||||
result->nodePtr = currentNode;
|
result->nodePtr = currentNode;
|
||||||
|
|
||||||
Type* LeftOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[0]->result;
|
Expression* lhs = ((Expression**) ParentExpression->impl.operation.operands->data)[0];
|
||||||
Type* RightOperandType = ((Expression**) ParentExpression->impl.operation.operands->data)[1]->result;
|
Expression* rhs = ((Expression**) ParentExpression->impl.operation.operands->data)[1];
|
||||||
|
|
||||||
|
Type* LeftOperandType = lhs->result;
|
||||||
|
Type* RightOperandType = rhs->result;
|
||||||
|
|
||||||
//should not be a box or a reference
|
//should not be a box or a reference
|
||||||
if (LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite) {
|
if (LeftOperandType->kind != TypeKindPrimitive && LeftOperandType->kind != TypeKindComposite) {
|
||||||
return 1;
|
print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite) {
|
if (RightOperandType->kind != TypeKindPrimitive && RightOperandType->kind != TypeKindComposite) {
|
||||||
return 1;
|
print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive) {
|
if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindPrimitive) {
|
||||||
if(LeftOperandType->impl.primitive == Float || RightOperandType->impl.primitive == Float){
|
|
||||||
return 1;
|
if (LeftOperandType->impl.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (RightOperandType->impl.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
result->kind = TypeKindPrimitive;
|
result->kind = TypeKindPrimitive;
|
||||||
result->impl.primitive = Int;
|
result->impl.primitive = Int;
|
||||||
|
|
||||||
} else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite) {
|
} else if (LeftOperandType->kind == TypeKindPrimitive && RightOperandType->kind == TypeKindComposite) {
|
||||||
if(LeftOperandType->impl.primitive == Float || RightOperandType->impl.composite.primitive == Float){
|
|
||||||
return 1;
|
if (LeftOperandType->impl.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
if((int)RightOperandType->impl.composite.scale != 1){
|
|
||||||
return 1;
|
if (RightOperandType->impl.composite.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->kind = TypeKindPrimitive;
|
result->kind = TypeKindPrimitive;
|
||||||
result->impl.primitive = Int;
|
result->impl.primitive = Int;
|
||||||
|
|
||||||
}else if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive) {
|
}else if (LeftOperandType->kind == TypeKindComposite && RightOperandType->kind == TypeKindPrimitive) {
|
||||||
if(LeftOperandType->impl.composite.primitive == Float || RightOperandType->impl.primitive == Float){
|
|
||||||
return 1;
|
if (LeftOperandType->impl.composite.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
if((int)LeftOperandType->impl.composite.scale != 1){
|
|
||||||
return 1;
|
if (RightOperandType->impl.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->kind = TypeKindPrimitive;
|
result->kind = TypeKindPrimitive;
|
||||||
result->impl.primitive = Int;
|
result->impl.primitive = Int;
|
||||||
} else {
|
} else {
|
||||||
if(LeftOperandType->impl.composite.primitive == Float || RightOperandType->impl.composite.primitive == Float){
|
|
||||||
return 1;
|
if (RightOperandType->impl.composite.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &rhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LeftOperandType->impl.composite.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &lhs->nodePtr->location, Error, "Must be a type variant of int");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isScaleEqual(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale)) {
|
if (!isScaleEqual(LeftOperandType->impl.composite.scale, RightOperandType->impl.composite.scale)) {
|
||||||
return 1;
|
print_diagnostic(current_file, ¤tNode->location, Error, "Operands must be of equal size");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->kind = TypeKindComposite;
|
result->kind = TypeKindComposite;
|
||||||
result->impl.composite.nodePtr = currentNode;
|
result->impl.composite.nodePtr = currentNode;
|
||||||
result->impl.composite.scale = LeftOperandType->impl.composite.scale;
|
result->impl.composite.scale = LeftOperandType->impl.composite.scale;
|
||||||
|
@ -781,7 +901,7 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode
|
||||||
//fill Operand
|
//fill Operand
|
||||||
Expression* expression = createExpression(currentNode->children[0]);
|
Expression* expression = createExpression(currentNode->children[0]);
|
||||||
if(NULL == expression){
|
if(NULL == expression){
|
||||||
return 1;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
g_array_append_val(ParentExpression->impl.operation.operands , expression);
|
g_array_append_val(ParentExpression->impl.operation.operands , expression);
|
||||||
|
|
||||||
|
@ -792,17 +912,22 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode
|
||||||
Type* result = malloc(sizeof(Type));
|
Type* result = malloc(sizeof(Type));
|
||||||
result->nodePtr = currentNode;
|
result->nodePtr = currentNode;
|
||||||
|
|
||||||
|
|
||||||
if (Operand->kind == TypeKindPrimitive) {
|
if (Operand->kind == TypeKindPrimitive) {
|
||||||
|
|
||||||
if (Operand->impl.primitive == Float) {
|
if (Operand->impl.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand type must be a variant of int");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->kind = TypeKindPrimitive;
|
result->kind = TypeKindPrimitive;
|
||||||
result->impl.primitive = Int;
|
result->impl.primitive = Int;
|
||||||
}else if(Operand->kind == TypeKindComposite) {
|
}else if(Operand->kind == TypeKindComposite) {
|
||||||
|
|
||||||
if (Operand->impl.composite.primitive == Float) {
|
if (Operand->impl.composite.primitive == Float) {
|
||||||
|
print_diagnostic(current_file, &Operand->nodePtr->location, Error, "Operand type must be a variant of int");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->kind = TypeKindComposite;
|
result->kind = TypeKindComposite;
|
||||||
result->impl.composite.nodePtr = currentNode;
|
result->impl.composite.nodePtr = currentNode;
|
||||||
result->impl.composite.primitive = Int;
|
result->impl.composite.primitive = Int;
|
||||||
|
@ -811,12 +936,12 @@ int createBitNotOperation(Expression* ParentExpression, AST_NODE_PTR currentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
ParentExpression->result = result;
|
ParentExpression->result = result;
|
||||||
|
|
||||||
return SEMANTIC_OK;
|
return SEMANTIC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray* getBoxMember(Type* currentBoxType, GArray *names) {
|
GArray* getBoxMember(Type* currentBoxType, GArray *names) {
|
||||||
|
|
||||||
|
|
||||||
GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember));
|
GArray *members = g_array_new(FALSE, FALSE, sizeof(BoxMember));
|
||||||
GHashTable* memberList = currentBoxType->impl.box.member;
|
GHashTable* memberList = currentBoxType->impl.box.member;
|
||||||
|
|
||||||
|
@ -850,6 +975,7 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) {
|
||||||
int status = getVariableFromScope(boxname, &boxVariable);
|
int status = getVariableFromScope(boxname, &boxVariable);
|
||||||
|
|
||||||
if(status == SEMANTIC_ERROR){
|
if(status == SEMANTIC_ERROR){
|
||||||
|
print_diagnostic(current_file, ¤tNode->children[0]->location, Error, "Variable of name `%s` does not exist");
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
Type* boxType;
|
Type* boxType;
|
||||||
|
@ -865,6 +991,7 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) {
|
||||||
if (boxType->kind != TypeKindBox) {
|
if (boxType->kind != TypeKindBox) {
|
||||||
return SEMANTIC_ERROR;
|
return SEMANTIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filling boxAccess variable
|
// filling boxAccess variable
|
||||||
ParentExpression->impl.variable->kind = VariableKindBoxMember;
|
ParentExpression->impl.variable->kind = VariableKindBoxMember;
|
||||||
ParentExpression->impl.variable->nodePtr = currentNode;
|
ParentExpression->impl.variable->nodePtr = currentNode;
|
||||||
|
@ -876,8 +1003,16 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) {
|
||||||
|
|
||||||
//first one is the box itself
|
//first one is the box itself
|
||||||
GArray* names = malloc(sizeof(GArray));
|
GArray* names = malloc(sizeof(GArray));
|
||||||
|
if(currentNode->kind == AST_IdentList){
|
||||||
for (size_t i = 1; i < currentNode->child_count; i++){
|
for (size_t i = 1; i < currentNode->child_count; i++){
|
||||||
g_array_append_val(names, currentNode->children[1]->value);
|
g_array_append_val(names, currentNode->children[i]->value);
|
||||||
|
}
|
||||||
|
}else if(currentNode->kind == AST_List){
|
||||||
|
for (size_t i = 1; i < currentNode->children[1]->child_count; i++){
|
||||||
|
g_array_append_val(names, currentNode->children[1]->children[i]->value);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
PANIC("current Node is not an Access");
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray * boxMember = getBoxMember(boxType, names);
|
GArray * boxMember = getBoxMember(boxType, names);
|
||||||
|
@ -887,6 +1022,50 @@ int createBoxAccess(Expression* ParentExpression,AST_NODE_PTR currentNode) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int createTypeCast(Expression* ParentExpression, AST_NODE_PTR currentNode){
|
||||||
|
ParentExpression->impl.typecast.nodePtr = currentNode;
|
||||||
|
|
||||||
|
ParentExpression->impl.typecast.operand = createExpression(currentNode->children[0]);
|
||||||
|
if (ParentExpression->impl.typecast.operand == NULL){
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* target = malloc(sizeof(Type));
|
||||||
|
int status = get_type_impl(currentNode->children[1], &target);
|
||||||
|
if (status) {
|
||||||
|
print_diagnostic(current_file, ¤tNode->children[1]->location, Error, "Unknown type");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
ParentExpression->impl.typecast.targetType = target;
|
||||||
|
ParentExpression->result = target;
|
||||||
|
|
||||||
|
return SEMANTIC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int createTransmute(Expression* ParentExpression, AST_NODE_PTR currentNode){
|
||||||
|
ParentExpression->impl.transmute.nodePtr = currentNode;
|
||||||
|
ParentExpression->impl.transmute.operand = createExpression(currentNode->children[0]);
|
||||||
|
|
||||||
|
if (ParentExpression->impl.transmute.operand == NULL){
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* target = malloc(sizeof(Type));
|
||||||
|
int status = get_type_impl(currentNode->children[1], &target);
|
||||||
|
if (status){
|
||||||
|
print_diagnostic(current_file, ¤tNode->children[1]->location, Error, "Unknown type");
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParentExpression->impl.typecast.targetType = target;
|
||||||
|
ParentExpression->result = target;
|
||||||
|
|
||||||
|
return SEMANTIC_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Expression *createExpression(AST_NODE_PTR currentNode){
|
Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
Expression *expression = malloc(sizeof(Expression));
|
Expression *expression = malloc(sizeof(Expression));
|
||||||
expression->nodePtr = currentNode;
|
expression->nodePtr = currentNode;
|
||||||
|
@ -908,6 +1087,7 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
int status = getVariableFromScope(currentNode->value, &expression->impl.variable );
|
int status = getVariableFromScope(currentNode->value, &expression->impl.variable );
|
||||||
if(status == SEMANTIC_ERROR){
|
if(status == SEMANTIC_ERROR){
|
||||||
DEBUG("Identifier is not in current scope");
|
DEBUG("Identifier is not in current scope");
|
||||||
|
print_diagnostic(current_file, ¤tNode->location, Error, "Variable not found");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
switch (expression->impl.variable->kind) {
|
switch (expression->impl.variable->kind) {
|
||||||
|
@ -975,16 +1155,24 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_IdentList:
|
case AST_IdentList:
|
||||||
expression->kind = ExpressionKindVariable;
|
|
||||||
|
|
||||||
//Box Accsess
|
|
||||||
case AST_List:
|
case AST_List:
|
||||||
// Box Self Access
|
expression->kind = ExpressionKindVariable;
|
||||||
case AST_Typekind:
|
if(createBoxAccess(expression, currentNode)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AST_Typecast:
|
||||||
|
expression->kind = ExpressionKindTypeCast;
|
||||||
|
if(createTypeCast(expression, currentNode)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case AST_Transmute:
|
case AST_Transmute:
|
||||||
|
expression->kind = ExpressionKindTransmute;
|
||||||
|
if(createTransmute(expression, currentNode)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PANIC("Node is not an expression but from kind: %i", currentNode->kind);
|
PANIC("Node is not an expression but from kind: %i", currentNode->kind);
|
||||||
break;
|
break;
|
||||||
|
@ -993,10 +1181,152 @@ Expression *createExpression(AST_NODE_PTR currentNode){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int createAssign(Statement* ParentStatement, AST_NODE_PTR currentNode){
|
||||||
|
Assignment assign;
|
||||||
|
assign.nodePtr = currentNode;
|
||||||
|
const char* varName = currentNode->children[0]->value;
|
||||||
|
|
||||||
|
int status = getVariableFromScope(varName, &assign.variable);
|
||||||
|
if(status){
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
assign.value = createExpression(currentNode->children[1]);
|
||||||
|
if(assign.value == NULL){
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParentStatement->impl.assignment = assign;
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
Statement *createStatement(AST_NODE_PTR currentNode);
|
||||||
|
|
||||||
|
int createWhile(Statement * ParentStatement, AST_NODE_PTR currentNode){
|
||||||
|
assert(ParentExpression == NULL);
|
||||||
|
assert(currentNode == NULL);
|
||||||
|
assert(currentNode->kind == AST_While);
|
||||||
|
|
||||||
|
While whileStruct;
|
||||||
|
whileStruct.nodePtr = currentNode;
|
||||||
|
whileStruct.conditon = createExpression(currentNode->children[0]);
|
||||||
|
if(NULL == whileStruct.conditon){
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
AST_NODE_PTR statementList = currentNode->children[1];
|
||||||
|
whileStruct.block.nodePtr = statementList;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < statementList->child_count; i++){
|
||||||
|
Statement* statement = createStatement(statementList->children[i]);
|
||||||
|
if (NULL == statement) {
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
g_array_append_val(whileStruct.block.statemnts, statement);
|
||||||
|
}
|
||||||
|
ParentStatement->impl.whileLoop = whileStruct;
|
||||||
|
|
||||||
|
return SEMANTIC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fillBlock(Block * block,AST_NODE_PTR currentNode){
|
||||||
|
block->nodePtr = currentNode;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < currentNode->child_count; i++){
|
||||||
|
Statement* statement = createStatement(currentNode->children[i]);
|
||||||
|
if(statement == NULL){
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
g_array_append_val(block->statemnts,statement);
|
||||||
|
}
|
||||||
|
return SEMANTIC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int createIf(Branch* Parentbranch, AST_NODE_PTR currentNode){
|
||||||
|
If ifbranch;
|
||||||
|
ifbranch.nodePtr = currentNode;
|
||||||
|
|
||||||
|
Expression* expression = createExpression(currentNode->children[0]);
|
||||||
|
if (NULL == expression) {
|
||||||
|
return SEMANTIC_ERROR;
|
||||||
|
}
|
||||||
|
ifbranch.conditon = expression;
|
||||||
|
int status = fillBlock(&ifbranch.block, currentNode->children[1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int createBranch(Statement* ParentStatement,AST_NODE_PTR currentNode){
|
||||||
|
Branch Branch;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < currentNode->child_count; i++ ){
|
||||||
|
switch (currentNode->children[i]->kind){
|
||||||
|
case AST_If:
|
||||||
|
createIf(&Branch, currentNode->children[i]);
|
||||||
|
case AST_IfElse:
|
||||||
|
case AST_Else:
|
||||||
|
default:
|
||||||
|
PANIC("current node is not part of a Branch")
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement *createStatement(AST_NODE_PTR currentNode){
|
||||||
|
Statement* statement = malloc(sizeof(Statement));
|
||||||
|
statement->nodePtr = currentNode;
|
||||||
|
|
||||||
|
switch(currentNode->kind){
|
||||||
|
case AST_Decl:
|
||||||
|
statement->kind = StatementKindDeclaration;
|
||||||
|
|
||||||
|
case AST_Def:
|
||||||
|
statement->kind = StatementKindDefinition;
|
||||||
|
case AST_While:
|
||||||
|
statement->kind = StatementKindWhile;
|
||||||
|
if(createWhile(statement, currentNode)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
case AST_Stmt:
|
||||||
|
statement->kind = StatementKindBranch;
|
||||||
|
//ifbrnches:
|
||||||
|
|
||||||
|
case AST_Assign:
|
||||||
|
statement->kind = StatementKindAssignment;
|
||||||
|
if(createAssign(statement, currentNode)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
case AST_Call:
|
||||||
|
//both funcall and boxfuncall
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Function *createFunction(AST_NODE_PTR currentNode){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxType *createBox(AST_NODE_PTR currentNode){
|
||||||
|
BoxType * box = malloc(sizeof(BoxType));
|
||||||
|
|
||||||
|
box->nodePtr = currentNode;
|
||||||
|
|
||||||
|
//
|
||||||
|
//box
|
||||||
|
// name
|
||||||
|
// list
|
||||||
|
// decl
|
||||||
|
// def // change BoxMember to have an
|
||||||
|
// fun //create static function
|
||||||
|
// a.b(dsadsadas)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Module *create_set(AST_NODE_PTR currentNode){
|
Module *create_set(AST_NODE_PTR currentNode){
|
||||||
DEBUG("create root Module");
|
DEBUG("create root Module");
|
||||||
|
@ -1053,7 +1383,9 @@ Module *create_set(AST_NODE_PTR currentNode){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AST_Box:
|
case AST_Box:
|
||||||
|
|
||||||
case AST_Fun:
|
case AST_Fun:
|
||||||
|
case AST_Typedef:
|
||||||
case AST_Import:
|
case AST_Import:
|
||||||
DEBUG("create Import");
|
DEBUG("create Import");
|
||||||
g_array_append_val(imports, currentNode->children[i]->value);
|
g_array_append_val(imports, currentNode->children[i]->value);
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
|
|
||||||
|
// with of primitive types (int/float) in bytes
|
||||||
|
#define BASE_BYTES 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Primitive types form the basis of all other types.
|
* @brief Primitive types form the basis of all other types.
|
||||||
*
|
*
|
||||||
|
@ -36,7 +39,7 @@ typedef enum Sign_t {
|
||||||
typedef double Scale;
|
typedef double Scale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A composite type is an extended definiton of a primitive type.
|
* @brief A composite type is an extended definition of a primitive type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct CompositeType_t {
|
typedef struct CompositeType_t {
|
||||||
|
@ -124,7 +127,7 @@ typedef struct Typedefine_t {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reprents the value of type. Can be used to definitons, initialization and for expressions contants.
|
* @brief Reprents the value of type. Can be used to definitions, initialization and for expressions contants.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct TypeValue_t {
|
typedef struct TypeValue_t {
|
||||||
|
@ -183,7 +186,7 @@ typedef enum ParameterKind_t {
|
||||||
} ParameterKind;
|
} ParameterKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A parameter can either be a declaration or a definiton
|
* @brief A parameter can either be a declaration or a definition
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct Parameter_t {
|
typedef struct Parameter_t {
|
||||||
|
@ -245,7 +248,7 @@ typedef struct VariableDeclaration_t {
|
||||||
} VariableDeclaration;
|
} VariableDeclaration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Definiton of a variable
|
* @brief Definition of a variable
|
||||||
*
|
*
|
||||||
* @attention NOTE: The types of the initializer and the declaration must be equal
|
* @attention NOTE: The types of the initializer and the declaration must be equal
|
||||||
*
|
*
|
||||||
|
@ -455,7 +458,7 @@ typedef struct Block_t {
|
||||||
// '------------------------------------------------'
|
// '------------------------------------------------'
|
||||||
|
|
||||||
typedef struct While_t {
|
typedef struct While_t {
|
||||||
Expression conditon;
|
Expression *conditon;
|
||||||
Block block;
|
Block block;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} While;
|
} While;
|
||||||
|
@ -465,13 +468,13 @@ typedef struct While_t {
|
||||||
// '------------------------------------------------'
|
// '------------------------------------------------'
|
||||||
|
|
||||||
typedef struct If_t {
|
typedef struct If_t {
|
||||||
Expression conditon;
|
Expression *conditon;
|
||||||
Block block;
|
Block block;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} If;
|
} If;
|
||||||
|
|
||||||
typedef struct ElseIf_t {
|
typedef struct ElseIf_t {
|
||||||
Expression conditon;
|
Expression *conditon;
|
||||||
Block block;
|
Block block;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} ElseIf;
|
} ElseIf;
|
||||||
|
@ -495,7 +498,7 @@ typedef struct Branch_t {
|
||||||
|
|
||||||
typedef struct Assignment_t {
|
typedef struct Assignment_t {
|
||||||
Variable* variable;
|
Variable* variable;
|
||||||
Expression value;
|
Expression* value;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Assignment;
|
} Assignment;
|
||||||
|
|
||||||
|
@ -504,7 +507,9 @@ typedef enum StatementKind_t {
|
||||||
StatementKindFunctionBoxCall,
|
StatementKindFunctionBoxCall,
|
||||||
StatementKindWhile,
|
StatementKindWhile,
|
||||||
StatementKindBranch,
|
StatementKindBranch,
|
||||||
StatementKindAssignment
|
StatementKindAssignment,
|
||||||
|
StatementKindDeclaration,
|
||||||
|
StatementKindDefinition
|
||||||
} StatementKind;
|
} StatementKind;
|
||||||
|
|
||||||
typedef struct Statement_t {
|
typedef struct Statement_t {
|
||||||
|
@ -515,6 +520,7 @@ typedef struct Statement_t {
|
||||||
While whileLoop;
|
While whileLoop;
|
||||||
Branch branch;
|
Branch branch;
|
||||||
Assignment assignment;
|
Assignment assignment;
|
||||||
|
Variable variable;
|
||||||
} impl;
|
} impl;
|
||||||
AST_NODE_PTR nodePtr;
|
AST_NODE_PTR nodePtr;
|
||||||
} Statement;
|
} Statement;
|
||||||
|
|
Loading…
Reference in New Issue