comptut

changeset 0:10f07b308aab tutor2

tutor2.txt completed
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 15 Mar 2015 05:47:44 +0200
parents
children d872095206bf
files .hgignore COMPILE Makefile RUN src/main.c
diffstat 5 files changed, 255 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Sun Mar 15 05:47:44 2015 +0200
     1.3 @@ -0,0 +1,5 @@
     1.4 +\.o$
     1.5 +\.s$
     1.6 +\.swp$
     1.7 +^test$
     1.8 +^a\.out$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/COMPILE	Sun Mar 15 05:47:44 2015 +0200
     2.3 @@ -0,0 +1,5 @@
     2.4 +#!/bin/sh
     2.5 +
     2.6 +./test >out.s && \
     2.7 +	as --32 -o out.o out.s && \
     2.8 +	ld -m elf_i386 out.o
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Makefile	Sun Mar 15 05:47:44 2015 +0200
     3.3 @@ -0,0 +1,12 @@
     3.4 +src = $(wildcard src/*.c)
     3.5 +obj = $(src:.c=.o)
     3.6 +bin = test
     3.7 +
     3.8 +CFLAGS = -pedantic -Wall -g
     3.9 +
    3.10 +$(bin): $(obj)
    3.11 +	$(CC) -o $@ $(obj) $(LDFLAGS)
    3.12 +
    3.13 +.PHONY: clean
    3.14 +clean:
    3.15 +	rm -f $(obj) $(bin)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/RUN	Sun Mar 15 05:47:44 2015 +0200
     4.3 @@ -0,0 +1,3 @@
     4.4 +#!/bin/sh
     4.5 +
     4.6 +./a.out; echo $?
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/main.c	Sun Mar 15 05:47:44 2015 +0200
     5.3 @@ -0,0 +1,230 @@
     5.4 +#include <stdio.h>
     5.5 +#include <stdlib.h>
     5.6 +#include <ctype.h>
     5.7 +#include <stdarg.h>
     5.8 +
     5.9 +void init(void);
    5.10 +void expression(void);
    5.11 +void term(void);
    5.12 +void factor(void);
    5.13 +void add(void);
    5.14 +void sub(void);
    5.15 +void mul(void);
    5.16 +void divide(void);
    5.17 +void get_char(void);
    5.18 +void match(char c);
    5.19 +char get_name(void);
    5.20 +char get_num(void);
    5.21 +void stop(const char *s, ...);
    5.22 +void expected(const char *s);
    5.23 +void emit(const char *fmt, ...);
    5.24 +void vemit(const char *fmt, va_list ap);
    5.25 +void emitln(const char *fmt, ...);
    5.26 +int is_addsub(char c);
    5.27 +
    5.28 +FILE *infile, *outfile;
    5.29 +char look;
    5.30 +
    5.31 +static const char *prologue =
    5.32 +	"\t.globl _start\n"
    5.33 +	"_start:\n"
    5.34 +	"\tcall main\n"
    5.35 +	"\tmov %eax, %ebx\n"
    5.36 +	"\tmov $1, %eax\n"
    5.37 +	"\tint $0x80\n"
    5.38 +	"main:\n"
    5.39 +	"\t# ---- START ----\n";
    5.40 +
    5.41 +static const char *epilogue = "\t# ---- END ----\n\tret\n";
    5.42 +
    5.43 +int main(void)
    5.44 +{
    5.45 +	infile = stdin;
    5.46 +	outfile = stdout;
    5.47 +
    5.48 +	init();
    5.49 +	/* output prologue */
    5.50 +	fputs(prologue, outfile);
    5.51 +
    5.52 +	expression();
    5.53 +
    5.54 +	/* output epilogue */
    5.55 +	fputs(epilogue, outfile);
    5.56 +	return 0;
    5.57 +}
    5.58 +
    5.59 +void init(void)
    5.60 +{
    5.61 +	get_char();
    5.62 +}
    5.63 +
    5.64 +void expression(void)
    5.65 +{
    5.66 +	if(is_addsub(look)) {
    5.67 +		emitln("xor %%eax, %%eax");
    5.68 +	} else {
    5.69 +		term();
    5.70 +	}
    5.71 +
    5.72 +	while(is_addsub(look)) {
    5.73 +		emitln("push %%eax");
    5.74 +		switch(look) {
    5.75 +		case '+':
    5.76 +			add();
    5.77 +			break;
    5.78 +		case '-':
    5.79 +			sub();
    5.80 +			break;
    5.81 +		default:
    5.82 +			expected("addop");
    5.83 +		}
    5.84 +	}
    5.85 +}
    5.86 +
    5.87 +void term(void)
    5.88 +{
    5.89 +	factor();
    5.90 +	while(look == '*' || look == '/') {
    5.91 +		emitln("push %%eax");
    5.92 +		switch(look) {
    5.93 +		case '*':
    5.94 +			mul();
    5.95 +			break;
    5.96 +		case '/':
    5.97 +			divide();
    5.98 +			break;
    5.99 +		default:
   5.100 +			expected("mulop");
   5.101 +		}
   5.102 +	}
   5.103 +}
   5.104 +
   5.105 +void factor(void)
   5.106 +{
   5.107 +	if(look == '(') {
   5.108 +		match('(');
   5.109 +		expression();
   5.110 +		match(')');
   5.111 +	} else {
   5.112 +		emitln("mov $%c, %%eax", get_num());
   5.113 +	}
   5.114 +}
   5.115 +
   5.116 +void add(void)
   5.117 +{
   5.118 +	match('+');
   5.119 +	term();
   5.120 +	emitln("pop %%ebx");
   5.121 +	emitln("add %%ebx, %%eax");
   5.122 +}
   5.123 +
   5.124 +void sub(void)
   5.125 +{
   5.126 +	match('-');
   5.127 +	term();
   5.128 +	emitln("pop %%ebx");
   5.129 +	emitln("sub %%ebx, %%eax");
   5.130 +	emitln("neg %%eax");
   5.131 +}
   5.132 +
   5.133 +void mul(void)
   5.134 +{
   5.135 +	match('*');
   5.136 +	factor();
   5.137 +	emitln("pop %%ebx");
   5.138 +	emitln("imul %%ebx");
   5.139 +}
   5.140 +
   5.141 +void divide(void)
   5.142 +{
   5.143 +	match('/');
   5.144 +	factor();
   5.145 +	emitln("mov %%eax, %%ebx");
   5.146 +	emitln("pop %%eax");
   5.147 +	emitln("idiv %%ebx");
   5.148 +}
   5.149 +
   5.150 +void get_char(void)
   5.151 +{
   5.152 +	look = fgetc(infile);
   5.153 +}
   5.154 +
   5.155 +void match(char c)
   5.156 +{
   5.157 +	if(look == c) {
   5.158 +		get_char();
   5.159 +	} else {
   5.160 +		char s[2] = {0, 0};
   5.161 +		s[0] = c;
   5.162 +		expected(s);
   5.163 +	}
   5.164 +}
   5.165 +
   5.166 +char get_name(void)
   5.167 +{
   5.168 +	char res;
   5.169 +	if(!isalpha(look)) {
   5.170 +		expected("name");
   5.171 +	}
   5.172 +	res = toupper(look);
   5.173 +	get_char();
   5.174 +	return res;
   5.175 +}
   5.176 +
   5.177 +char get_num(void)
   5.178 +{
   5.179 +	char res;
   5.180 +	if(!isdigit(look)) {
   5.181 +		expected("integer");
   5.182 +	}
   5.183 +	res = look;
   5.184 +	get_char();
   5.185 +	return res;
   5.186 +}
   5.187 +
   5.188 +void stop(const char *s, ...)
   5.189 +{
   5.190 +	va_list ap;
   5.191 +
   5.192 +	fprintf(stderr, "error: ");
   5.193 +	va_start(ap, s);
   5.194 +	vfprintf(stderr, s, ap);
   5.195 +	va_end(ap);
   5.196 +	fputc('\n', stderr);
   5.197 +
   5.198 +	abort();
   5.199 +}
   5.200 +
   5.201 +void expected(const char *s)
   5.202 +{
   5.203 +	stop("%s expected", s);
   5.204 +}
   5.205 +
   5.206 +void emit(const char *fmt, ...)
   5.207 +{
   5.208 +	va_list ap;
   5.209 +	va_start(ap, fmt);
   5.210 +	vemit(fmt, ap);
   5.211 +	va_end(ap);
   5.212 +}
   5.213 +
   5.214 +void vemit(const char *fmt, va_list ap)
   5.215 +{
   5.216 +	fputc('\t', outfile);
   5.217 +	vfprintf(outfile, fmt, ap);
   5.218 +}
   5.219 +
   5.220 +void emitln(const char *fmt, ...)
   5.221 +{
   5.222 +	va_list ap;
   5.223 +	va_start(ap, fmt);
   5.224 +	vemit(fmt, ap);
   5.225 +	va_end(ap);
   5.226 +	fputc('\n', outfile);
   5.227 +}
   5.228 +
   5.229 +
   5.230 +int is_addsub(char c)
   5.231 +{
   5.232 +	return c == '+' || c == '-';
   5.233 +}