diff --git a/cinc.xcodeproj/project.pbxproj b/cinc.xcodeproj/project.pbxproj index 129f18c..4809f4b 100644 --- a/cinc.xcodeproj/project.pbxproj +++ b/cinc.xcodeproj/project.pbxproj @@ -12,6 +12,8 @@ F65A954E21454B31005FCAF5 /* token.c in Sources */ = {isa = PBXBuildFile; fileRef = F65A954D21454B31005FCAF5 /* token.c */; }; F661C333214590930021FCCE /* parser.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C332214590930021FCCE /* parser.c */; }; F661C3362145CE760021FCCE /* ast.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C3352145CE760021FCCE /* ast.c */; }; + F661C3392145D9C40021FCCE /* generate.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C3382145D9C40021FCCE /* generate.c */; }; + F661C33C2145DF370021FCCE /* out.s in Sources */ = {isa = PBXBuildFile; fileRef = F661C33B2145DF370021FCCE /* out.s */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -31,12 +33,15 @@ F61910602142A876003B8798 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; F61910672142A8C5003B8798 /* tokenize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tokenize.h; sourceTree = ""; }; F61910682142A8C5003B8798 /* tokenize.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tokenize.c; sourceTree = ""; }; - F65A954C21454B21005FCAF5 /* token.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = token.h; path = ../../../../token.h; sourceTree = ""; }; F65A954D21454B31005FCAF5 /* token.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = token.c; sourceTree = ""; }; F661C331214590930021FCCE /* parser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = ""; }; F661C332214590930021FCCE /* parser.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = parser.c; sourceTree = ""; }; F661C3342145CE760021FCCE /* ast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ast.h; sourceTree = ""; }; F661C3352145CE760021FCCE /* ast.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ast.c; sourceTree = ""; }; + F661C3372145D9C40021FCCE /* generate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = generate.h; sourceTree = ""; }; + F661C3382145D9C40021FCCE /* generate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = generate.c; sourceTree = ""; }; + F661C33A2145DE300021FCCE /* token.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = ""; }; + F661C33B2145DF370021FCCE /* out.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = out.s; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -73,11 +78,14 @@ F61910672142A8C5003B8798 /* tokenize.h */, F61910682142A8C5003B8798 /* tokenize.c */, F65A954D21454B31005FCAF5 /* token.c */, - F65A954C21454B21005FCAF5 /* token.h */, + F661C33A2145DE300021FCCE /* token.h */, F661C331214590930021FCCE /* parser.h */, F661C332214590930021FCCE /* parser.c */, F661C3342145CE760021FCCE /* ast.h */, F661C3352145CE760021FCCE /* ast.c */, + F661C3372145D9C40021FCCE /* generate.h */, + F661C3382145D9C40021FCCE /* generate.c */, + F661C33B2145DF370021FCCE /* out.s */, ); path = cinc; sourceTree = ""; @@ -139,9 +147,11 @@ buildActionMask = 2147483647; files = ( F65A954E21454B31005FCAF5 /* token.c in Sources */, + F661C33C2145DF370021FCCE /* out.s in Sources */, F661C3362145CE760021FCCE /* ast.c in Sources */, F61910692142A8C5003B8798 /* tokenize.c in Sources */, F661C333214590930021FCCE /* parser.c in Sources */, + F661C3392145D9C40021FCCE /* generate.c in Sources */, F61910612142A876003B8798 /* main.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/cinc/ast.c b/cinc/ast.c index 026e865..bfc5428 100644 --- a/cinc/ast.c +++ b/cinc/ast.c @@ -8,7 +8,7 @@ #include "ast.h" #include - +#include #define AST_CHILDREN_START 10 AstNode* make_node(const char* data) { @@ -29,6 +29,22 @@ void add_child(AstNode* parent,AstNode* child) { parent->num_children++; } +void print_tree(AstNode* root,int tabLevel) { + if (tabLevel==0) { + printf("Root: %s\n",root->data); + } + if ((root->num_children)>0) { + for (int i=0;i<(root->num_children);i++) { + for (int i=0;ichildren[i]->data); + print_tree(root->children[i],tabLevel+1); + } + } +} + void free_tree(AstNode* root) { if (root->children) { for (int i=0;i<(root->num_children);i++) { diff --git a/cinc/ast.h b/cinc/ast.h index 61e8da6..e2eadd5 100644 --- a/cinc/ast.h +++ b/cinc/ast.h @@ -20,6 +20,7 @@ typedef struct _astnode AstNode; AstNode* make_node(const char* data); void add_child(AstNode* parent,AstNode* child); +void print_tree(AstNode* root,int tabLevel); void free_tree(AstNode* root); #endif /* ast_h */ diff --git a/cinc/generate.c b/cinc/generate.c new file mode 100644 index 0000000..dc995c8 --- /dev/null +++ b/cinc/generate.c @@ -0,0 +1,58 @@ +// +// generate.c +// cinc +// +// Created by Peter Terpstra on 9/9/18. +// Copyright © 2018 Peter Terpstra. All rights reserved. +// + +#include "generate.h" +#include "ast.h" +#include +#include +#include + +static char* prg_asm; + +static void generate_expr(AstNode* ast) { + const char* type=ast->data; + if(strcmp("num", type)==0) { + strncat(prg_asm, "mov rax,", 8); + strncat(prg_asm,ast->children[0]->data,strlen(ast->children[0]->data)); + strncat(prg_asm, "\n", 1); + } +} + + +static void generate_statement(AstNode* ast) { + const char* type=ast->data; + if(strcmp("return", type)==0) { + generate_expr(ast->children[0]); + strncat(prg_asm, "ret\n", 4); + } +} + +static void generate_block(AstNode* ast) { + for (int i=0;i<(ast->num_children);i++) { + generate_statement(ast->children[i]); + } +} + + +static void generate_func(AstNode* ast) { + const char* name=ast->children[1]->data; + strncat(prg_asm, ".globl _", 8); + strncat(prg_asm, name, strlen(name)); + strncat(prg_asm, "\n_", 2); + strncat(prg_asm, name, strlen(name)); + strncat(prg_asm, ":\n", 2); + generate_block(ast->children[2]); +} + + +char* generate_prg(AstNode* ast) { + prg_asm=malloc(sizeof(char)); + prg_asm[0]=0; + generate_func(ast); + return prg_asm; +} diff --git a/cinc/generate.h b/cinc/generate.h new file mode 100644 index 0000000..567b518 --- /dev/null +++ b/cinc/generate.h @@ -0,0 +1,16 @@ +// +// generate.h +// cinc +// +// Created by Peter Terpstra on 9/9/18. +// Copyright © 2018 Peter Terpstra. All rights reserved. +// + +#ifndef generate_h +#define generate_h + +#include "ast.h" +char* generate_prg(AstNode* ast); + + +#endif /* generate_h */ diff --git a/cinc/main.c b/cinc/main.c index 8ea8dfe..77a17b9 100644 --- a/cinc/main.c +++ b/cinc/main.c @@ -12,10 +12,17 @@ #include "tokenize.h" #include "ast.h" #include "parser.h" +#include "generate.h" int main(int argc, const char * argv[]) { char* prgstr="int main() {\nreturn 0;\n}"; Token* tokens=tokenize(prgstr); AstNode* ast=parse(tokens); free_toklist(tokens); + char* prg=generate_prg(ast); + free_tree(ast); + FILE* outfile=fopen("/Users/peterterpstra/Desktop/projects/xcode/cinc/cinc/out.s","w"); + fputs(prg, outfile); + fclose(outfile); + free(prg); } diff --git a/cinc/out.s b/cinc/out.s new file mode 100644 index 0000000..f64fe9f --- /dev/null +++ b/cinc/out.s @@ -0,0 +1,4 @@ +.globl _main +_main: +mov rax,0 +ret diff --git a/cinc/token.h b/cinc/token.h new file mode 100644 index 0000000..032447a --- /dev/null +++ b/cinc/token.h @@ -0,0 +1,48 @@ +// +// token.h +// cinc +// +// Created by Peter Terpstra on 9/7/18. +// Copyright © 2018 Peter Terpstra. All rights reserved. +// + +#ifndef token_h +#define token_h + +#include + +typedef enum { + intval, + strval +} TokenValType; + +typedef struct { + TokenValType type; + bool constflag; + union { + int intval; + char* strval; + }; +} TokenVal; + + +#define TYPE_IDENT 128 +#define TYPE_NUM 129 +#define TYPE_EOF 130 +#define TYPE_RETURN 131 +#define TYPE_TYPE 132 + +struct _token { + unsigned char type; + TokenVal* val; + struct _token* next; +}; + +typedef struct _token Token; + +Token* new_token(unsigned char type,TokenVal* val, Token* prev); +void print_tok(Token* tok); +TokenVal* val_from_int(int val); +TokenVal* val_from_const_str(const char* val); +TokenVal* val_from_str(char* val); +#endif /* token_h */