restructure build process

generics
cosmonaut 2021-04-28 16:01:48 -07:00
parent 272c809c69
commit 49183bf1d3
8 changed files with 182 additions and 87 deletions

View File

@ -40,10 +40,14 @@ add_executable(
lib/dropt/dropt_handlers.c
# Source
src/ast.h
src/compiler.h
src/parser.h
src/stack.h
src/ast.c
src/stack.c
src/compiler.c
src/parser.c
src/stack.c
src/main.c
# Generated code
${BISON_Parser_OUTPUTS}
${FLEX_Scanner_OUTPUTS}

41
example.w Normal file
View File

@ -0,0 +1,41 @@
struct YourStruct
{
yourInt: int;
}
struct MyStruct
{
myInt: int;
myBool: bool;
yourStructReference: Reference<YourStruct>;
yourStruct: YourStruct;
Increment(): void
{
myInt = myInt + 1;
}
static MyFunction(input: int): int
{
return input * 2;
}
}
struct Program
{
static Main(): int
{
myStruct: MyStruct;
myReference: Reference<MyStruct>;
myInt: int;
myReference = alloc MyStruct;
myInt = MyStruct.MyFunction(2);
myStruct.myInt = myInt;
myStruct.Increment();
return myStruct.myInt;
}
}

View File

@ -7,7 +7,7 @@
#include "../src/ast.h"
#include "../src/stack.h"
void yyerror(FILE *fp, Stack *stack, char *s)
void yyerror(FILE *fp, Stack *stack, Node **pRootNode, char *s)
{
fprintf (stderr, "%s\n", s);
}
@ -15,8 +15,6 @@ void yyerror(FILE *fp, Stack *stack, char *s)
extern char *yytext;
extern int yylex (void);
extern FILE *yyin;
extern Node *rootNode;
%}
%define api.value.type {struct Node*}
@ -62,7 +60,7 @@ extern Node *rootNode;
%token COMMENT
%token NEWLINE
%parse-param { FILE* fp } { Stack *stack }
%parse-param { FILE* fp } { Stack *stack } { Node **pRootNode }
%define parse.error verbose
@ -82,7 +80,7 @@ Program : TopLevelDeclarations
PopStackFrame(stack);
rootNode = declarationSequence;
*pRootNode = declarationSequence;
}
BaseType : VOID

View File

@ -13,14 +13,7 @@
#include <llvm-c/TargetMachine.h>
#include <llvm-c/Target.h>
#include "y.tab.h"
#include "ast.h"
#include "stack.h"
#include "../lib/dropt/dropt.h"
extern FILE *yyin;
Stack *stack;
Node *rootNode;
typedef struct LocalVariable
{
@ -820,26 +813,17 @@ static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
}
}
static int Build(char *inputFilename, uint32_t optimizationLevel)
int Build(Node *node, uint32_t optimizationLevel)
{
scope = CreateScope();
structTypeDeclarations = NULL;
structTypeDeclarationCount = 0;
stack = CreateStack();
FILE *fp = fopen(inputFilename, "r");
yyin = fp;
yyparse(fp, stack);
fclose(fp);
PrintTree(rootNode, 0);
LLVMModuleRef module = LLVMModuleCreateWithName("my_module");
LLVMContextRef context = LLVMGetGlobalContext();
Compile(module, context, rootNode);
Compile(module, context, node);
/* add main call */
LLVMBuilderRef builder = LLVMCreateBuilder();
@ -886,11 +870,6 @@ static int Build(char *inputFilename, uint32_t optimizationLevel)
LLVMPassManagerRef passManager = LLVMCreatePassManager();
// LLVMAddInstructionCombiningPass(passManager);
// LLVMAddCFGSimplificationPass(passManager);
// LLVMAddReassociatePass(passManager);
// LLVMAddPromoteMemoryToRegisterPass(passManager);
LLVMPassManagerBuilderRef passManagerBuilder = LLVMPassManagerBuilderCreate();
LLVMPassManagerBuilderSetOptLevel(passManagerBuilder, optimizationLevel);
LLVMPassManagerBuilderPopulateModulePassManager(passManagerBuilder, passManager);
@ -931,61 +910,3 @@ static int Build(char *inputFilename, uint32_t optimizationLevel)
return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
dropt_bool showHelp;
uint32_t optimizationLevel = 0;
char *inputFilename;
extern int yydebug;
int exitCode = EXIT_SUCCESS;
dropt_option options[] = {
{ 'h', "help", "Shows help.", NULL, dropt_handle_bool, &showHelp, dropt_attr_halt },
{ 'O', "optimize", "Sets optimization level of the output IR. Must be a value between 0 and 3.", "number", dropt_handle_uint, &optimizationLevel },
{ 0 } /* Required sentinel value. */
};
dropt_context *droptContext = dropt_new_context(options);
if (droptContext == NULL)
{
exitCode = EXIT_FAILURE;
}
else if (argc == 0)
{
printf("Must supply an input file.");
exitCode = EXIT_FAILURE;
}
else
{
char** rest = dropt_parse(droptContext, -1, &argv[1]);
if (dropt_get_error(droptContext) != dropt_error_none)
{
fprintf(stderr, "wraith: %s\n", dropt_get_error_message(droptContext));
exitCode = EXIT_FAILURE;
}
else if (showHelp)
{
printf("Usage: wraith [options] [--] [input_file]\n\n"
"Options:\n");
dropt_print_help(stdout, droptContext, NULL);
}
else
{
yydebug = 1; /* FIXME: make this an option */
inputFilename = *rest;
if (inputFilename == NULL)
{
fprintf(stderr, "ERROR: Must provide an input file.\n");
exitCode = EXIT_FAILURE;
}
else
{
exitCode = Build(inputFilename, optimizationLevel);
}
}
}
return exitCode;
}

8
src/compiler.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef WRAITH_COMPILER_H
#define WRAITH_COMPILER_H
#include "ast.h"
int Build(Node *node, uint32_t optimizationLevel);
#endif /* WRAITH_COMPILER_H */

74
src/main.c Normal file
View File

@ -0,0 +1,74 @@
#include <stdlib.h>
#include "../lib/dropt/dropt.h"
#include "parser.h"
#include "compiler.h"
int main(int argc, char *argv[])
{
dropt_bool showHelp = 0;
dropt_bool parseVerbose = 0;
uint32_t optimizationLevel = 0;
char *inputFilename;
int exitCode = EXIT_SUCCESS;
dropt_option options[] = {
{ 'h', "help", "Shows help.", NULL, dropt_handle_bool, &showHelp, dropt_attr_halt },
{ 'v', "parse-verbose", "Shows verbose parser output.", NULL, dropt_handle_bool, &parseVerbose },
{ 'O', "optimize", "Sets optimization level of the output IR. Must be a value between 0 and 3.", "number", dropt_handle_uint, &optimizationLevel },
{ 0 } /* Required sentinel value. */
};
dropt_context *droptContext = dropt_new_context(options);
if (droptContext == NULL)
{
exitCode = EXIT_FAILURE;
}
else if (argc == 0)
{
printf("Must supply an input file.");
exitCode = EXIT_FAILURE;
}
else
{
char** rest = dropt_parse(droptContext, -1, &argv[1]);
if (dropt_get_error(droptContext) != dropt_error_none)
{
fprintf(stderr, "wraith: %s\n", dropt_get_error_message(droptContext));
exitCode = EXIT_FAILURE;
}
else if (showHelp)
{
printf("Usage: wraith [options] [--] [input_file]\n\n"
"Options:\n");
dropt_print_help(stdout, droptContext, NULL);
}
else
{
/* TODO: free AST after compilation */
inputFilename = *rest;
if (inputFilename == NULL)
{
fprintf(stderr, "ERROR: Must provide an input file.\n");
exitCode = EXIT_FAILURE;
}
else
{
Node *rootNode;
if (Parse(inputFilename, &rootNode, parseVerbose) != 0)
{
fprintf(stderr, "Parser error.\n");
exitCode = EXIT_FAILURE;
}
else
{
exitCode = Build(rootNode, optimizationLevel);
}
}
}
}
return exitCode;
}

41
src/parser.c Normal file
View File

@ -0,0 +1,41 @@
#include <stdio.h>
#include "y.tab.h"
#include "ast.h"
#include "stack.h"
extern FILE *yyin;
extern int yydebug;
int Parse(char *inputFilename, Node **pRootNode, uint8_t parseVerbose)
{
int result;
Stack *stack = CreateStack();
yydebug = parseVerbose;
FILE *fp = fopen(inputFilename, "r");
yyin = fp;
result = yyparse(fp, stack, pRootNode);
fclose(fp);
/* TODO: free stack */
/* TODO: free AST on error */
if (result == 0)
{
if (parseVerbose)
{
PrintTree(*pRootNode, 0);
}
}
else if (result == 1)
{
fprintf(stderr, "Syntax error.\n");
}
else if (result == 2)
{
fprintf(stderr, "Out of memory.\n");
}
return result;
}

8
src/parser.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef WRAITH_PARSER_H
#define WRAITH_PARSER_H
#include "ast.h"
int Parse(char *inputFilename, Node **pNode, uint8_t parseVerbose);
#endif /* WRAITH_PARSER_H */