Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"milestone-5/cpp08": "1.1.0",
"milestone-5/cpp09": "1.0.1",
"milestone-5/inception": "1.0.0",
"pcc/b": "0.0.0",
"pcc/libasm": "1.0.0",
"rushes/hotrace": "2.1.0",
"rushes/libunit": "1.0.0",
Expand Down
4 changes: 4 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
# ASM
nasm

# Compiler compilers
bison # yacc
flex # lex

# Rust
pkg-config
rustc
Expand Down
1 change: 1 addition & 0 deletions milestone-5/cpp09/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.0
4 changes: 4 additions & 0 deletions pcc/b/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
B
*.h
*.c

24 changes: 24 additions & 0 deletions pcc/b/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
NAME = B
CC = gcc
CFLAGS = -Wall -Wextra -Werror

all: $(NAME)

$(NAME): y.tab.c lex.yy.c
$(CC) $(CFLAGS) -o $(NAME) y.tab.c lex.yy.c

y.tab.c y.tab.h: parser.y
yacc -d parser.y

lex.yy.c: lexer.l y.tab.h
lex lexer.l

clean:
rm -f lex.yy.c y.tab.c y.tab.h

fclean: clean
rm -f $(NAME)

re: fclean all

.PHONY: all clean fclean re
40 changes: 40 additions & 0 deletions pcc/b/lexer.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
%{
#include "y.tab.h" // tokens generated by yacc
#include <stdlib.h>

// The below 'option' call voids some unused functions
// Older versions of lex might not recognize this line
%}

%option nounput noinput

%%

"auto" { return AUTO; }
"extrn" { return EXTERN; }

[a-zA-Z_][a-zA-Z0-9_]* {
yylval.str = strdup(yytext); // dupe
return IDENTIFIER;
}

[0-9]+ {
yylval.num = atoi(yytext);
return NUMBER;
}

[ \t\n]+ { /* ignore whitespaces */ }

"=" { return EQUALS; }
";" { return SEMICOLON; }
"," { return ','; }
"(" { return '('; }
")" { return ')'; }
"{" { return '{'; }
"}" { return '}'; }

%%

int yywrap() {
return 1;
}
138 changes: 138 additions & 0 deletions pcc/b/parser.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <search.h>

int yylex(void);
void yyerror(const char *s);

typedef enum {
TYPE_AUTO,
TYPE_EXTERN
} SymbolType;

typedef struct {
char *name;
SymbolType type;
int offset; // ebp
} Symbol;

void *sym_table = NULL;
int current_local_offset = -4;

// required by tsearch
int compare_symbols(const void *pa, const void *pb) {
return strcmp(((const Symbol *)pa)->name, ((const Symbol *)pb)->name);
}

void add_symbol(char *name, SymbolType type) {
Symbol *sym = malloc(sizeof(Symbol));
sym->name = strdup(name);
sym->type = type;

if (type == TYPE_AUTO) {
sym->offset = current_local_offset;
// shift down 4 for next var
current_local_offset -= 4;
} else {
// extern symbols don't use edp offset
sym->offset = 0;
}

// insertion
Symbol **found = tsearch(sym, &sym_table, compare_symbols);
if (*found != sym) {
// var was already in the tree
free(sym->name);
free(sym);
}
}

Symbol *get_symbol(char *name) {
Symbol dummy;
dummy.name = name;
Symbol **found = tfind(&dummy, &sym_table, compare_symbols);
if (found) {
return *found;
}
return NULL;
}
%}

%union {
int num;
char *str;
}

%token <str> IDENTIFIER
%token <num> NUMBER
%token EQUALS SEMICOLON AUTO EXTERN

%%

program:
| program statement
| program function_definition
;

declarations:
| declarations declaration
;

declaration:
AUTO auto_list SEMICOLON
| EXTERN extrn_list SEMICOLON
;

auto_list:
IDENTIFIER { add_symbol($1, TYPE_AUTO); }
| auto_list ',' IDENTIFIER { add_symbol($3, TYPE_AUTO); }
;

extrn_list:
IDENTIFIER { add_symbol($1, TYPE_EXTERN); }
| extrn_list ',' IDENTIFIER { add_symbol($3, TYPE_EXTERN); }
;

statements_list:
| statements_list statement
;

statement:
IDENTIFIER EQUALS NUMBER SEMICOLON {
Symbol *sym = get_symbol($1);

if (sym && sym->type == TYPE_AUTO) {
printf("\tmov eax, %d\n", $3);
printf("\tmov [ebp%d], eax ; store val in %s\n", sym->offset, $1);
} else
fprintf(stderr, "Error: Unknown or non-auto variable '%s'\n", $1);
}
;

function_definition:
IDENTIFIER '(' ')' '{' {
printf("%s:\n", $1);
printf("\t.long %s + 4\n", $1);
printf("\tenter 0, 0\n");
// reset offset tracker for new func
current_local_offset = -4;
}
declarations
statements_list
'}' {
printf("\tleave\n");
printf("\tret\n");
}
;

%%

void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}

int main(void) {
return yyparse();
}
4 changes: 4 additions & 0 deletions pcc/b/test1.b
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
main() {
i = 0;
}

6 changes: 6 additions & 0 deletions pcc/b/test2.b
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
main() {
auto i, s, x;
i = 0;
s = 42;
x = 100;
}
11 changes: 11 additions & 0 deletions pcc/b/test_final.b
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
main() {
extrn putchar, char;
auto i, s;
i = 0;
s = "hello, world\n";
while (char(s, i)) {
putchar(char(s, i));
i++;
}
}

1 change: 1 addition & 0 deletions pcc/b/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.0
1 change: 1 addition & 0 deletions pcc/libasm/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.0
1 change: 1 addition & 0 deletions piscine-c/c00/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.0
4 changes: 4 additions & 0 deletions release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@
"release-type": "simple",
"package-name": "inception"
},
"pcc/b": {
"release-type": "simple",
"package-name": "b"
},
"pcc/libasm": {
"release-type": "simple",
"package-name": "libasm"
Expand Down
Loading