Compare commits
2 Commits
85692497a6
...
1dfec8af24
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dfec8af24 | ||
|
|
f798fbe55f |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
/it0-out0.diff
|
/it0-out0.diff
|
||||||
/it1-out*
|
/it1-out*
|
||||||
/it2-out*
|
/it2-out*
|
||||||
|
/it3-out*
|
||||||
|
|||||||
82
Makefile
82
Makefile
@ -1,36 +1,70 @@
|
|||||||
TEE :=
|
.SUFFIXES:
|
||||||
|
|
||||||
GCC_FLAGS := -g -O0 -Wall
|
GCC_FLAGS := -g -O0 -Wall
|
||||||
|
|
||||||
run: it1 it2
|
|
||||||
|
|
||||||
it0:
|
|
||||||
echo "Hand made"
|
|
||||||
|
|
||||||
it1:
|
all: it2-out
|
||||||
cat it1-in.lang0 | python3 it0-out.py $(if $(TEE),| tee,> ) it1-out0.py
|
|
||||||
|
|
||||||
cat it1-in.lang0 | python3 it1-out0.py $(if $(TEE),| tee,> ) it1-out1.py
|
|
||||||
diff it1-out0.py it1-out1.py > it1-out1.diff
|
|
||||||
cat it1-in.lang0 | python3 it1-out1.py $(if $(TEE),| tee,> ) it1-out2.py
|
|
||||||
diff it1-out1.py it1-out2.py > it1-out2.diff
|
|
||||||
cat it1-in.lang0 | python3 it1-out2.py $(if $(TEE),| tee,> ) it1-out.py
|
|
||||||
diff it1-out2.py it1-out.py > it1-out.diff
|
|
||||||
|
|
||||||
# See how much our hand written code differs from resulting code
|
|
||||||
-diff it0-out.py it1-out0.py > it0-out0.diff
|
|
||||||
|
|
||||||
it2: it1
|
# it0-out.py => Hand made
|
||||||
cat it2-in.lang0 | python3 it1-out.py $(if $(TEE),| tee,> ) it2-out0.py
|
|
||||||
|
|
||||||
|
|
||||||
|
it1-out0.py: it0-out.py it1-in.lang0
|
||||||
|
cat it1-in.lang0 | python3 it0-out.py > it1-out0.py
|
||||||
|
|
||||||
|
it1-out1.py: it1-out0.py it1-in.lang0
|
||||||
|
cat it1-in.lang0 | python3 it1-out0.py > it1-out1.py
|
||||||
|
# We can diff here since the target hasn't changed
|
||||||
|
# The target for it0 is the same as for it1
|
||||||
|
diff it1-out0.py it1-out1.py
|
||||||
|
|
||||||
|
it1-out2.py: it1-out1.py it1-in.lang0
|
||||||
|
cat it1-in.lang0 | python3 it1-out1.py > it1-out2.py
|
||||||
|
diff it1-out1.py it1-out2.py
|
||||||
|
|
||||||
|
it1-out3.py: it1-out2.py it1-in.lang0
|
||||||
|
cat it1-in.lang0 | python3 it1-out2.py > it1-out3.py
|
||||||
|
diff it1-out2.py it1-out3.py
|
||||||
|
|
||||||
|
it1-out.py: it1-out3.py
|
||||||
|
cp it1-out3.py it1-out.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
it2-out0.py: it1-out.py it2-in.lang0
|
||||||
|
cat it2-in.lang0 | python3 it1-out.py > it2-out0.py
|
||||||
|
|
||||||
|
# No gcc step since the target is still python here
|
||||||
|
|
||||||
|
it2-out1.c: it2-out0.py it2-in.lang0
|
||||||
|
cat it2-in.lang0 | python3 it2-out0.py > it2-out1.c
|
||||||
|
# diff it2-out0.py it2-out1.py Do not diff - the target changed so the output will be different
|
||||||
|
|
||||||
|
it2-out1: it2-out1.c
|
||||||
|
gcc it2-out1.c -o it2-out1 $(GCC_FLAGS)
|
||||||
|
|
||||||
|
it2-out2.c: it2-out1 it2-in.lang0
|
||||||
|
cat it2-in.lang0 | ./it2-out1 > it2-out2.c
|
||||||
|
diff it2-out1.c it2-out2.c
|
||||||
|
|
||||||
|
it2-out2: it2-out2.c
|
||||||
|
gcc it2-out2.c -o it2-out2 $(GCC_FLAGS)
|
||||||
|
|
||||||
|
it2-out3.c: it2-out2 it2-in.lang0
|
||||||
|
cat it2-in.lang0 | ./it2-out2 > it2-out3.c
|
||||||
|
diff it2-out2.c it2-out3.c
|
||||||
|
|
||||||
|
it2-out3: it2-out3.c
|
||||||
|
gcc it2-out3.c -o it2-out3 $(GCC_FLAGS)
|
||||||
|
|
||||||
|
it2-out: it2-out3
|
||||||
|
cp it2-out3 it2-out
|
||||||
|
|
||||||
|
|
||||||
cat it2-in.lang0 | python3 it2-out0.py $(if $(TEE),| tee,> ) it2-out1.c && gcc it2-out1.c -o it2-out1 $(GCC_FLAGS)
|
|
||||||
# diff it2-out0.c it2-out1.c > it2-out1.diff
|
|
||||||
cat it2-in.lang0 | ./it2-out1 $(if $(TEE),| tee,> ) it2-out2.c && gcc it2-out2.c -o it2-out2 $(GCC_FLAGS)
|
|
||||||
diff it2-out1.c it2-out2.c > it2-out2.diff
|
|
||||||
cat it2-in.lang0 | ./it2-out2 $(if $(TEE),| tee,> ) it2-out.c && gcc it2-out.c -o it2-out $(GCC_FLAGS)
|
|
||||||
diff it2-out2.c it2-out.c > it2-out.diff
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm it1-out* it2-out*
|
-rm it1-out* it2-out*
|
||||||
|
-rm it1-out* it2-out* it3-out*
|
||||||
.PHONY: it2
|
|
||||||
|
|||||||
@ -154,10 +154,12 @@ How to run
|
|||||||
Install python3 and make
|
Install python3 and make
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make clean run
|
make clean all
|
||||||
```
|
```
|
||||||
|
|
||||||
Get more info
|
Get more info
|
||||||
```
|
```
|
||||||
make TRACE=1 clean run
|
make TRACE=1 clean all
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You will now have a lang0 compiler in python for python in `./it1-out.py`, and one written in C for C in `./it2-out`.
|
||||||
|
|||||||
434
it3-in.lang0
Normal file
434
it3-in.lang0
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
increaseindent indent:
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
return indent
|
||||||
|
/
|
||||||
|
|
||||||
|
lexident:
|
||||||
|
declare char
|
||||||
|
declare isbeforea
|
||||||
|
declare isafterz
|
||||||
|
declare word
|
||||||
|
set word ""
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isbeforea lt char "a"
|
||||||
|
if isbeforea
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc isafterz lt "z" char
|
||||||
|
if isafterz
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc word addstringchar word char
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
return word
|
||||||
|
/
|
||||||
|
|
||||||
|
parseconststring:
|
||||||
|
declare char
|
||||||
|
declare iseof
|
||||||
|
declare isquote
|
||||||
|
skipchar quote
|
||||||
|
emit quote
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseof eq char eof
|
||||||
|
if iseof
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc isquote eq char quote
|
||||||
|
if isquote
|
||||||
|
break
|
||||||
|
/
|
||||||
|
emit char
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
skipchar quote
|
||||||
|
emit quote
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprvarref:
|
||||||
|
declare varname
|
||||||
|
calc varname lexident
|
||||||
|
emit "var_"
|
||||||
|
emit varname
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprcall:
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare funcname
|
||||||
|
declare isspace
|
||||||
|
declare isnotspace
|
||||||
|
declare isfirst
|
||||||
|
declare isnotfirst
|
||||||
|
declare isquote
|
||||||
|
declare isnotquote
|
||||||
|
calc funcname lexident
|
||||||
|
emit funcname
|
||||||
|
emit "("
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
emit ")"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatdeclare indent:
|
||||||
|
declare var
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
emit indent
|
||||||
|
emit "push 0"
|
||||||
|
emit " ; "
|
||||||
|
emit var
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatset indent:
|
||||||
|
declare var
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "var_"
|
||||||
|
emit var
|
||||||
|
emit " = "
|
||||||
|
parseconststring
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatcalc indent:
|
||||||
|
declare var
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "var_"
|
||||||
|
emit var
|
||||||
|
emit " = "
|
||||||
|
parseexprcall
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseblock indent/
|
||||||
|
|
||||||
|
parsestatif indent:
|
||||||
|
declare indentt
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "if ( 0 < strlen("
|
||||||
|
parseexprvarref
|
||||||
|
emit ") )\n"
|
||||||
|
emit indent
|
||||||
|
emit "{\n"
|
||||||
|
skipchar eol
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "}\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatforever indent:
|
||||||
|
declare indentt
|
||||||
|
emit indent
|
||||||
|
emit "while (1)\n"
|
||||||
|
emit indent
|
||||||
|
emit "{\n"
|
||||||
|
skipchar eol
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "}\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatbreak indent:
|
||||||
|
emit indent
|
||||||
|
emit "break;\n"
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatreturn indent:
|
||||||
|
declare char
|
||||||
|
declare isspace
|
||||||
|
declare isnotspace
|
||||||
|
emit indent
|
||||||
|
emit "return "
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isspace
|
||||||
|
skip
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
if isnotspace
|
||||||
|
emit "0"
|
||||||
|
/
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestattrace indent:
|
||||||
|
declare varname
|
||||||
|
emit indent
|
||||||
|
emit "trace("
|
||||||
|
emit quote
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
emit varname
|
||||||
|
emit quote
|
||||||
|
emit ", var_"
|
||||||
|
emit varname
|
||||||
|
emit ");\n"
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestat indent:
|
||||||
|
declare call
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare iscall
|
||||||
|
declare isfirst
|
||||||
|
declare isspace
|
||||||
|
declare isquote
|
||||||
|
declare isnotfirst
|
||||||
|
declare isnotspace
|
||||||
|
declare isnotquote
|
||||||
|
calc call lexident
|
||||||
|
trace call
|
||||||
|
calc iscall eq call "declare"
|
||||||
|
if iscall
|
||||||
|
parsestatdeclare indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "set"
|
||||||
|
if iscall
|
||||||
|
parsestatset indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "calc"
|
||||||
|
if iscall
|
||||||
|
parsestatcalc indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "if"
|
||||||
|
if iscall
|
||||||
|
parsestatif indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "forever"
|
||||||
|
if iscall
|
||||||
|
parsestatforever indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "break"
|
||||||
|
if iscall
|
||||||
|
parsestatbreak indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "return"
|
||||||
|
if iscall
|
||||||
|
parsestatreturn indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "trace"
|
||||||
|
if iscall
|
||||||
|
parsestattrace indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
emit indent
|
||||||
|
emit call
|
||||||
|
emit "("
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
skipchar eol
|
||||||
|
emit ");\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseblock indent:
|
||||||
|
declare char
|
||||||
|
declare copy
|
||||||
|
declare iseol
|
||||||
|
declare isnoteol
|
||||||
|
declare isdone
|
||||||
|
declare iseoblock
|
||||||
|
forever
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseol eq char eol
|
||||||
|
calc isnoteol not iseol
|
||||||
|
if isnoteol
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
set copy " "
|
||||||
|
forever
|
||||||
|
calc isdone eq copy indent
|
||||||
|
if isdone
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skipchar "\t"
|
||||||
|
calc copy increaseindent copy
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
skip
|
||||||
|
skipchar eol
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skipchar "\t"
|
||||||
|
parsestat indent
|
||||||
|
/
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsefunc:
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare funcname
|
||||||
|
declare iseoblock
|
||||||
|
declare isfirst
|
||||||
|
declare isspace
|
||||||
|
declare isnotfirst
|
||||||
|
declare isnotspace
|
||||||
|
declare var
|
||||||
|
calc funcname lexident
|
||||||
|
trace funcname
|
||||||
|
emit "\n"
|
||||||
|
emit funcname
|
||||||
|
emit ":\n"
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc var lexident
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
skipchar "/"
|
||||||
|
skipchar eol
|
||||||
|
emit ");"
|
||||||
|
emit "\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
skipchar ":"
|
||||||
|
skipchar eol
|
||||||
|
parseblock " "
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitheader:
|
||||||
|
emit "section .text\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitfooter:
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
main:
|
||||||
|
declare char
|
||||||
|
declare iseof
|
||||||
|
declare iseol
|
||||||
|
declare isnoteol
|
||||||
|
emitheader
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseof eq char eof
|
||||||
|
if iseof
|
||||||
|
break
|
||||||
|
/
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseol eq char eol
|
||||||
|
calc isnoteol not iseol
|
||||||
|
if isnoteol
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
parsefunc
|
||||||
|
/
|
||||||
|
emitfooter
|
||||||
|
return
|
||||||
|
/
|
||||||
Loading…
x
Reference in New Issue
Block a user