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 */; };
|
F65A954E21454B31005FCAF5 /* token.c in Sources */ = {isa = PBXBuildFile; fileRef = F65A954D21454B31005FCAF5 /* token.c */; };
|
||||||
F661C333214590930021FCCE /* parser.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C332214590930021FCCE /* parser.c */; };
|
F661C333214590930021FCCE /* parser.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C332214590930021FCCE /* parser.c */; };
|
||||||
F661C3362145CE760021FCCE /* ast.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C3352145CE760021FCCE /* ast.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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@ -31,12 +33,15 @@
|
|||||||
F61910602142A876003B8798 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -73,11 +78,14 @@
|
|||||||
F61910672142A8C5003B8798 /* tokenize.h */,
|
F61910672142A8C5003B8798 /* tokenize.h */,
|
||||||
F61910682142A8C5003B8798 /* tokenize.c */,
|
F61910682142A8C5003B8798 /* tokenize.c */,
|
||||||
F65A954D21454B31005FCAF5 /* token.c */,
|
F65A954D21454B31005FCAF5 /* token.c */,
|
||||||
F65A954C21454B21005FCAF5 /* token.h */,
|
F661C33A2145DE300021FCCE /* token.h */,
|
||||||
F661C331214590930021FCCE /* parser.h */,
|
F661C331214590930021FCCE /* parser.h */,
|
||||||
F661C332214590930021FCCE /* parser.c */,
|
F661C332214590930021FCCE /* parser.c */,
|
||||||
F661C3342145CE760021FCCE /* ast.h */,
|
F661C3342145CE760021FCCE /* ast.h */,
|
||||||
F661C3352145CE760021FCCE /* ast.c */,
|
F661C3352145CE760021FCCE /* ast.c */,
|
||||||
|
F661C3372145D9C40021FCCE /* generate.h */,
|
||||||
|
F661C3382145D9C40021FCCE /* generate.c */,
|
||||||
|
F661C33B2145DF370021FCCE /* out.s */,
|
||||||
);
|
);
|
||||||
path = cinc;
|
path = cinc;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -139,9 +147,11 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
F65A954E21454B31005FCAF5 /* token.c in Sources */,
|
F65A954E21454B31005FCAF5 /* token.c in Sources */,
|
||||||
|
F661C33C2145DF370021FCCE /* out.s in Sources */,
|
||||||
F661C3362145CE760021FCCE /* ast.c in Sources */,
|
F661C3362145CE760021FCCE /* ast.c in Sources */,
|
||||||
F61910692142A8C5003B8798 /* tokenize.c in Sources */,
|
F61910692142A8C5003B8798 /* tokenize.c in Sources */,
|
||||||
F661C333214590930021FCCE /* parser.c in Sources */,
|
F661C333214590930021FCCE /* parser.c in Sources */,
|
||||||
|
F661C3392145D9C40021FCCE /* generate.c in Sources */,
|
||||||
F61910612142A876003B8798 /* main.c in Sources */,
|
F61910612142A876003B8798 /* main.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
18
cinc/ast.c
18
cinc/ast.c
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#define AST_CHILDREN_START 10
|
#define AST_CHILDREN_START 10
|
||||||
|
|
||||||
AstNode* make_node(const char* data) {
|
AstNode* make_node(const char* data) {
|
||||||
@ -29,6 +29,22 @@ void add_child(AstNode* parent,AstNode* child) {
|
|||||||
parent->num_children++;
|
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) {
|
void free_tree(AstNode* root) {
|
||||||
if (root->children) {
|
if (root->children) {
|
||||||
for (int i=0;i<(root->num_children);i++) {
|
for (int i=0;i<(root->num_children);i++) {
|
||||||
|
@ -20,6 +20,7 @@ typedef struct _astnode AstNode;
|
|||||||
|
|
||||||
AstNode* make_node(const char* data);
|
AstNode* make_node(const char* data);
|
||||||
void add_child(AstNode* parent,AstNode* child);
|
void add_child(AstNode* parent,AstNode* child);
|
||||||
|
void print_tree(AstNode* root,int tabLevel);
|
||||||
void free_tree(AstNode* root);
|
void free_tree(AstNode* root);
|
||||||
|
|
||||||
#endif /* ast_h */
|
#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 "tokenize.h"
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "generate.h"
|
||||||
|
|
||||||
int main(int argc, const char * argv[]) {
|
int main(int argc, const char * argv[]) {
|
||||||
char* prgstr="int main() {\nreturn 0;\n}";
|
char* prgstr="int main() {\nreturn 0;\n}";
|
||||||
Token* tokens=tokenize(prgstr);
|
Token* tokens=tokenize(prgstr);
|
||||||
AstNode* ast=parse(tokens);
|
AstNode* ast=parse(tokens);
|
||||||
free_toklist(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…
x
Reference in New Issue
Block a user