Commit 13f46714 authored by Adam Blank's avatar Adam Blank
Browse files

Initial commit

parents
No related merge requests found
Showing with 523 additions and 0 deletions
+523 -0
bin
out
progs/*.txt
asmgen:
script: "/testers/cs24/project03/asmgen/test"
CC = clang-with-asan
CFLAGS = -Iinclude -Wall -Wextra
ASM = clang
TESTS_1 = $(wildcard progs/stage1-*.bas)
TESTS_2 = $(TESTS_1) $(wildcard progs/stage2-*.bas)
TESTS_3 = $(TESTS_2) $(wildcard progs/stage3-*.bas)
TESTS_4 = $(TESTS_3) $(wildcard progs/stage4-*.bas)
TESTS_5 = $(TESTS_4) $(wildcard progs/stage5-*.bas)
TESTS_6 = $(TESTS_5) $(wildcard progs/stage6-*.bas)
TESTS_7 = $(TESTS_6) $(wildcard progs/stage7-*.bas)
test: test7
test1: $(TESTS_1:progs/%.bas=%-result)
test2: $(TESTS_2:progs/%.bas=%-result)
test3: $(TESTS_3:progs/%.bas=%-result)
test4: $(TESTS_4:progs/%.bas=%-result)
test5: $(TESTS_5:progs/%.bas=%-result)
test6: $(TESTS_6:progs/%.bas=%-result)
test7: $(TESTS_7:progs/%.bas=%-result)
out/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
bin/compiler: out/ast.o out/compile.o out/compiler.o out/parser.o
$(CC) $(CFLAGS) $^ -o $@
out/%.s: progs/%.bas bin/compiler
bin/compiler $< > $@
bin/%: out/%.s
$(ASM) -g $< -o $@
progs/%-expected.txt: progs/%.bas
grep '^#' $< | sed -e 's/#//' > $@
progs/%-actual.txt: bin/%
$< > $@
%-result: progs/%-expected.txt progs/%-actual.txt
diff -u $^ && echo PASSED test $(@F:-result=). || (echo FAILED test $(@F:-result=). Aborting.; false)
clean:
rm -f out/* bin/* progs/*.txt
.PRECIOUS: out/%.o out/%.s bin/% progs/%-expected.txt progs/%-actual.txt
#ifndef AST_H
#define AST_H
/**
* Definitions for the abstract syntax tree representation of TeenyBASIC.
* Parsing source code into an AST allows us to traverse it in a structured way.
* The AST is a recursive data structure consisting of several types of "nodes".
*/
#include <stdint.h>
/** The types of AST nodes */
typedef enum {
NUM,
BINARY_OP,
VAR,
PRINT,
LET,
LABEL,
GOTO,
COND
} node_type_t;
/** The base struct for all nodes */
typedef struct {
/**
* The node's type. Determines how to interpret the node.
* For example, if `node->type == BINARY_OP`,
* then `node` can be cast to a `binary_node_t *`.
*/
node_type_t type;
} node_t;
/** A number literal */
typedef struct {
node_t base;
/** The value of the literal */
int64_t value;
} num_node_t;
/**
* An expression representing a binary operation or comparison.
* For example, (1 + 2) would be represented as a binary_node_t with:
* op == '+'
* ((num_node_t *) left)->value == 1
* ((num_node_t *) right)->value == 2
*/
typedef struct {
node_t base;
/** The operator, either '+', '-', '*', '/', '<', '=', or '> */
char op;
/** The left-hand side of the expression */
node_t *left;
/** The right-hand side of the expression */
node_t *right;
} binary_node_t;
/** An expression that evaluates a variable */
typedef struct {
node_t base;
/** The variable whose value to read ('A' to 'Z') */
char name;
} var_node_t;
/** A PRINT statement */
typedef struct {
node_t base;
/** The expression to evaluate and print */
node_t *expr;
} print_node_t;
/** A LET statement */
typedef struct {
node_t base;
/** The variable to assign a value to ('A' to 'Z') */
char name;
/** The expression to evaluate and store in the variable */
node_t *value;
} let_node_t;
/** A label */
typedef struct {
node_t base;
/** The text of a label (e.g. "00", "10", etc. in the primes program) */
char *label;
} label_node_t;
/** A GOTO statement */
typedef struct {
node_t base;
/** The label to jump to (e.g. "80" in the primes program) */
char *label;
} goto_node_t;
/** An IF statement */
typedef struct {
node_t base;
/** The condition to check, a binary_op_t with operator '<', '=', or '>' */
node_t *condition;
/** The statement to run if the condition evaluates to true */
node_t *if_branch;
} cond_node_t;
/** Constructs a num_node_t */
node_t *init_num_node(char *num_as_str);
/** Constructs a binary_node_t */
node_t *init_binary_node(char op, node_t *left, node_t *right);
/** Constructs a var_node_t */
node_t *init_var_node(char name);
/** Constructs a print_node_t */
node_t *init_print_node(node_t *expr);
/** Constructs a let_node_t */
node_t *init_let_node(char name, node_t *value);
/** Constructs a label_node_t */
node_t *init_label_node(char *label);
/** Constructs a goto_node_t */
node_t *init_goto_node(char *label);
/** Constructs a cond_node_t */
node_t *init_cond_node(node_t *condition, node_t *if_branch);
/** Frees an AST node and all its descendants */
void free_ast(node_t *node);
/** Prints a string representation of an AST node to stderr */
void print_ast(node_t *node);
#endif /* AST_H */
#ifndef COMPILE_H
#define COMPILE_H
#include <stdbool.h>
#include "ast.h"
/**
* Prints x86-64 assembly code that implements the given TeenyBASIC statement.
* This function will be called on each statement in the TeenyBASIC program in order.
*
* @param node the statement to compile (either a PRINT, LET, label, GOTO, or IF)
* @return true iff compilation succeeds
*/
bool compile_ast(node_t *node);
#endif /* COMPILE_H */
#ifndef PARSER_H
#define PARSER_H
#include "ast.h"
/** Parses the next statement from the provided TeenyBASIC file into an AST */
node_t *parse(FILE *stream);
#endif /* PARSER_H */
#-1337
PRINT -1337
#42
PRINT 42
PRINT 71
PRINT -84
PRINT -88
PRINT -426
PRINT -571
PRINT 343
PRINT 46
PRINT 556
PRINT -815
PRINT 166
PRINT 679
PRINT 570
PRINT 942
PRINT 435
PRINT -422
PRINT 981
PRINT 447
PRINT 656
PRINT -473
PRINT -55
PRINT 238
PRINT 8
PRINT 161
PRINT 221
PRINT 759
PRINT -884
PRINT -572
PRINT 935
PRINT 431
PRINT -776
PRINT -258
PRINT -877
PRINT -427
PRINT 206
PRINT 931
PRINT -632
PRINT -351
PRINT 231
PRINT 990
PRINT 24
PRINT -839
PRINT 4
PRINT -752
PRINT 825
PRINT -686
PRINT 940
PRINT 813
PRINT 329
PRINT 468
PRINT -286
PRINT 758
PRINT 538
PRINT 404
PRINT 394
PRINT 286
PRINT 226
PRINT 294
PRINT -864
PRINT 308
PRINT -683
PRINT -513
PRINT 503
PRINT -153
PRINT 737
PRINT -515
PRINT 916
PRINT 906
PRINT 937
PRINT 433
PRINT 422
PRINT 313
PRINT -754
PRINT 97
PRINT 415
PRINT 837
PRINT -347
PRINT -239
PRINT 571
PRINT -676
PRINT -271
PRINT 634
PRINT 517
PRINT -722
PRINT -856
PRINT 555
PRINT -79
PRINT 498
PRINT 926
PRINT 809
PRINT -378
PRINT 49
PRINT 735
PRINT 741
PRINT -711
PRINT -275
PRINT -292
PRINT 79
PRINT -628
PRINT 189
PRINT 97
#71
#-84
#-88
#-426
#-571
#343
#46
#556
#-815
#166
#679
#570
#942
#435
#-422
#981
#447
#656
#-473
#-55
#238
#8
#161
#221
#759
#-884
#-572
#935
#431
#-776
#-258
#-877
#-427
#206
#931
#-632
#-351
#231
#990
#24
#-839
#4
#-752
#825
#-686
#940
#813
#329
#468
#-286
#758
#538
#404
#394
#286
#226
#294
#-864
#308
#-683
#-513
#503
#-153
#737
#-515
#916
#906
#937
#433
#422
#313
#-754
#97
#415
#837
#-347
#-239
#571
#-676
#-271
#634
#517
#-722
#-856
#555
#-79
#498
#926
#809
#-378
#49
#735
#741
#-711
#-275
#-292
#79
#-628
#189
#97
#2
PRINT 1 + 1
#6
PRINT 1 + 2 + 3
#6
PRINT 1 + 5
#6
PRINT 5 + 1
PRINT 1
PRINT 2 + 1
PRINT 3 + (2 + 1)
PRINT 4 + (3 + (2 + 1))
PRINT 5 + (4 + (3 + (2 + 1)))
PRINT 6 + (5 + (4 + (3 + (2 + 1))))
PRINT 7 + (6 + (5 + (4 + (3 + (2 + 1)))))
PRINT 8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))
PRINT 9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1)))))))
PRINT 10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))))
PRINT 11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1)))))))))
PRINT 12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))))))
PRINT 13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1)))))))))))
PRINT 14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))))))))
PRINT 15 + (14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1)))))))))))))
PRINT 16 + (15 + (14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))))))))))
PRINT 17 + (16 + (15 + (14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1)))))))))))))))
PRINT 18 + (17 + (16 + (15 + (14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))))))))))))
PRINT 19 + (18 + (17 + (16 + (15 + (14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1)))))))))))))))))
PRINT 20 + (19 + (18 + (17 + (16 + (15 + (14 + (13 + (12 + (11 + (10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + 1))))))))))))))))))
#1
#3
#6
#10
#15
#21
#28
#36
#45
#55
#66
#78
#91
#105
#120
#136
#153
#171
#190
#210
#9223372036854775807
#-9223372036854775808
PRINT 9223372036854775807
PRINT 9223372036854775807 + 1
#11
PRINT 5 + 2 * 3
This diff is collapsed.
#-9223372036854775805
PRINT 4611686018427387905 + 4611686018427387906 # (1 << 62 | 1) + (1 << 62 | 2)
#3
PRINT -9223372036854775807 + -9223372036854775806 # (1 << 63 | 1) + (1 << 63 | 2)
#-1
PRINT +9223372036854775807 - -9223372036854775808 # ((1 << 63) - 1) - (1 << 63)
#-9223372036854775808
PRINT 0 - -9223372036854775808 # 0 - (1 << 63)
#-9223372036854775808
PRINT -9223372036854775808 * -1 # (1 << 63) * -1
#-9223372036854775808
PRINT -1 * -9223372036854775808 # -1 * (1 << 63)
#2174462994023308633
PRINT +1234567890123 * +9876543210987
#-2174462994023308633
PRINT -1234567890123 * +9876543210987
#-2174462994023308633
PRINT +1234567890123 * -9876543210987
#2174462994023308633
PRINT -1234567890123 * -9876543210987
#-5044783335869382975
PRINT 1234567890123 * (1234567890123 * (1234567890123 * (1234567890123 *
(1234567890123 * (1234567890123 * (1234567890123 * (1234567890123 *
(1234567890123 * (1234567890123 * (1234567890123 * (1234567890123 *
(1234567890123 * (1234567890123 * (1234567890123 * 1234567890123))))))))))))))
#0
PRINT 0 / 1
#10
PRINT 10 / 1
#6
PRINT 20 / 3
#0
PRINT 23 / 24
#5
PRINT +100 / +20
#-5
PRINT -100 / +20
#-5
PRINT +100 / -20
#5
PRINT -100 / -20
#33
PRINT +100 / +3
#-33
PRINT -100 / +3
#-33
PRINT +100 / -3
#33
PRINT -100 / -3
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment