Working compiler!!
This commit is contained in:
parent
b94fa9d49a
commit
36270c87a4
@ -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 = "<group>"; };
|
||||
F61910672142A8C5003B8798 /* tokenize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tokenize.h; sourceTree = "<group>"; };
|
||||
F61910682142A8C5003B8798 /* tokenize.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tokenize.c; sourceTree = "<group>"; };
|
||||
F65A954C21454B21005FCAF5 /* token.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = token.h; path = ../../../../token.h; sourceTree = "<group>"; };
|
||||
F65A954D21454B31005FCAF5 /* token.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = token.c; sourceTree = "<group>"; };
|
||||
F661C331214590930021FCCE /* parser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
|
||||
F661C332214590930021FCCE /* parser.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = parser.c; sourceTree = "<group>"; };
|
||||
F661C3342145CE760021FCCE /* ast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ast.h; sourceTree = "<group>"; };
|
||||
F661C3352145CE760021FCCE /* ast.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ast.c; sourceTree = "<group>"; };
|
||||
F661C3372145D9C40021FCCE /* generate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = generate.h; sourceTree = "<group>"; };
|
||||
F661C3382145D9C40021FCCE /* generate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = generate.c; sourceTree = "<group>"; };
|
||||
F661C33A2145DE300021FCCE /* token.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = "<group>"; };
|
||||
F661C33B2145DF370021FCCE /* out.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = out.s; sourceTree = "<group>"; };
|
||||
/* 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 = "<group>";
|
||||
@ -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;
|
||||
|
18
cinc/ast.c
18
cinc/ast.c
@ -8,7 +8,7 @@
|
||||
|
||||
#include "ast.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#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;i<tabLevel;i++) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("Child %d: ",i);
|
||||
printf("%s\n",root->children[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++) {
|
||||
|
@ -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 */
|
||||
|
58
cinc/generate.c
Normal file
58
cinc/generate.c
Normal file
@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
16
cinc/generate.h
Normal file
16
cinc/generate.h
Normal file
@ -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 */
|
@ -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);
|
||||
}
|
||||
|
4
cinc/out.s
Normal file
4
cinc/out.s
Normal file
@ -0,0 +1,4 @@
|
||||
.globl _main
|
||||
_main:
|
||||
mov rax,0
|
||||
ret
|
48
cinc/token.h
Normal file
48
cinc/token.h
Normal file
@ -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 <stdbool.h>
|
||||
|
||||
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 */
|
Loading…
Reference in New Issue
Block a user