Adds iteration 2, targeting the C language
This commit is contained in:
parent
5939b7cba5
commit
6e151be2b1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/it0-out0.diff
|
/it0-out0.diff
|
||||||
/it1-out*
|
/it1-out*
|
||||||
|
/it2-out*
|
||||||
|
|||||||
27
Makefile
27
Makefile
@ -1,17 +1,36 @@
|
|||||||
TEE :=
|
TEE :=
|
||||||
|
|
||||||
run:
|
GCC_FLAGS := -g -O0 -Wall
|
||||||
|
|
||||||
|
run: it1 it2
|
||||||
|
|
||||||
|
it0:
|
||||||
|
echo "Hand made"
|
||||||
|
|
||||||
|
it1:
|
||||||
cat it1-in.lang0 | python3 it0-out.py $(if $(TEE),| tee,> ) it1-out0.py
|
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
|
cat it1-in.lang0 | python3 it1-out0.py $(if $(TEE),| tee,> ) it1-out1.py
|
||||||
diff it1-out0.py it1-out1.py > it1-out1.diff
|
diff it1-out0.py it1-out1.py > it1-out1.diff
|
||||||
cat it1-in.lang0 | python3 it1-out1.py $(if $(TEE),| tee,> ) it1-out2.py
|
cat it1-in.lang0 | python3 it1-out1.py $(if $(TEE),| tee,> ) it1-out2.py
|
||||||
diff it1-out1.py it1-out2.py > it1-out2.diff
|
diff it1-out1.py it1-out2.py > it1-out2.diff
|
||||||
cat it1-in.lang0 | python3 it1-out2.py $(if $(TEE),| tee,> ) it1-out3.py
|
cat it1-in.lang0 | python3 it1-out2.py $(if $(TEE),| tee,> ) it1-out.py
|
||||||
diff it1-out2.py it1-out3.py > it1-out3.diff
|
diff it1-out2.py it1-out.py > it1-out.diff
|
||||||
|
|
||||||
# See how much our hand written code differs from resulting code
|
# See how much our hand written code differs from resulting code
|
||||||
-diff it0-out.py it1-out0.py > it0-out0.diff
|
-diff it0-out.py it1-out0.py > it0-out0.diff
|
||||||
|
|
||||||
|
it2: it1
|
||||||
|
cat it2-in.lang0 | python3 it1-out.py $(if $(TEE),| tee,> ) it2-out0.py
|
||||||
|
|
||||||
|
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*
|
-rm it1-out* it2-out*
|
||||||
|
|
||||||
|
.PHONY: it2
|
||||||
|
|||||||
19
it0-out.py
19
it0-out.py
@ -95,6 +95,11 @@ def parseexprcall():
|
|||||||
|
|
||||||
emit(')')
|
emit(')')
|
||||||
|
|
||||||
|
def parsestatdeclare(indent):
|
||||||
|
skipchar(' ')
|
||||||
|
var = lexident()
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
def parsestatset(indent):
|
def parsestatset(indent):
|
||||||
skipchar(' ')
|
skipchar(' ')
|
||||||
var = lexident()
|
var = lexident()
|
||||||
@ -195,6 +200,10 @@ def parsestat(indent):
|
|||||||
call = lexident()
|
call = lexident()
|
||||||
trace('call', call)
|
trace('call', call)
|
||||||
|
|
||||||
|
if call == "declare":
|
||||||
|
parsestatdeclare(indent)
|
||||||
|
return
|
||||||
|
|
||||||
if call == "set":
|
if call == "set":
|
||||||
parsestatset(indent)
|
parsestatset(indent)
|
||||||
return
|
return
|
||||||
@ -269,6 +278,7 @@ def parseblock(indent):
|
|||||||
|
|
||||||
def parsefunc():
|
def parsefunc():
|
||||||
funcname = lexident()
|
funcname = lexident()
|
||||||
|
|
||||||
trace('funcname', funcname)
|
trace('funcname', funcname)
|
||||||
emit('def ')
|
emit('def ')
|
||||||
emit(funcname)
|
emit(funcname)
|
||||||
@ -283,6 +293,15 @@ def parsefunc():
|
|||||||
emit(var)
|
emit(var)
|
||||||
first = False
|
first = False
|
||||||
|
|
||||||
|
if '/' == peek():
|
||||||
|
# Ahead declaration
|
||||||
|
skipchar('/')
|
||||||
|
skipchar(eol)
|
||||||
|
emit("):\n")
|
||||||
|
emit(" pass # ahead declaration\n")
|
||||||
|
emit("\n")
|
||||||
|
return
|
||||||
|
|
||||||
skipchar(':')
|
skipchar(':')
|
||||||
skipchar(eol)
|
skipchar(eol)
|
||||||
|
|
||||||
|
|||||||
29
it1-in.lang0
29
it1-in.lang0
@ -7,6 +7,7 @@ increaseindent indent:
|
|||||||
/
|
/
|
||||||
|
|
||||||
lexident:
|
lexident:
|
||||||
|
declare word
|
||||||
set word ""
|
set word ""
|
||||||
forever
|
forever
|
||||||
calc char peek
|
calc char peek
|
||||||
@ -81,6 +82,12 @@ parseexprcall:
|
|||||||
emit ")"
|
emit ")"
|
||||||
/
|
/
|
||||||
|
|
||||||
|
parsestatdeclare indent:
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar eol
|
||||||
|
/
|
||||||
|
|
||||||
parsestatset indent:
|
parsestatset indent:
|
||||||
skipchar " "
|
skipchar " "
|
||||||
calc var lexident
|
calc var lexident
|
||||||
@ -105,6 +112,8 @@ parsestatcalc indent:
|
|||||||
skipchar eol
|
skipchar eol
|
||||||
/
|
/
|
||||||
|
|
||||||
|
parseblock indent/
|
||||||
|
|
||||||
parsestatif indent:
|
parsestatif indent:
|
||||||
skipchar " "
|
skipchar " "
|
||||||
emit indent
|
emit indent
|
||||||
@ -194,6 +203,11 @@ parsestatskipchar indent:
|
|||||||
parsestat indent:
|
parsestat indent:
|
||||||
calc call lexident
|
calc call lexident
|
||||||
trace call
|
trace call
|
||||||
|
calc isset eq call "declare"
|
||||||
|
if isset
|
||||||
|
parsestatdeclare indent
|
||||||
|
return
|
||||||
|
/
|
||||||
calc isset eq call "set"
|
calc isset eq call "set"
|
||||||
if isset
|
if isset
|
||||||
parsestatset indent
|
parsestatset indent
|
||||||
@ -305,6 +319,11 @@ parseblock indent:
|
|||||||
|
|
||||||
parsefunc:
|
parsefunc:
|
||||||
calc funcname lexident
|
calc funcname lexident
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
return
|
||||||
|
/
|
||||||
trace funcname
|
trace funcname
|
||||||
emit "def "
|
emit "def "
|
||||||
emit funcname
|
emit funcname
|
||||||
@ -327,6 +346,16 @@ parsefunc:
|
|||||||
emit var
|
emit var
|
||||||
set first "0"
|
set first "0"
|
||||||
/
|
/
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
skipchar "/"
|
||||||
|
skipchar eol
|
||||||
|
emit "):\n"
|
||||||
|
emit " pass # ahead declaration\n"
|
||||||
|
emit "\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
skipchar ":"
|
skipchar ":"
|
||||||
skipchar eol
|
skipchar eol
|
||||||
emit "):\n"
|
emit "):\n"
|
||||||
|
|||||||
584
it2-in.lang0
Normal file
584
it2-in.lang0
Normal file
@ -0,0 +1,584 @@
|
|||||||
|
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 "char * var_"
|
||||||
|
emit var
|
||||||
|
emit ";"
|
||||||
|
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
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatemit indent:
|
||||||
|
declare char
|
||||||
|
declare isquote
|
||||||
|
declare isnotquote
|
||||||
|
emit indent
|
||||||
|
emit "emit("
|
||||||
|
skipchar " "
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
emit ");\n"
|
||||||
|
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
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatskipchar indent:
|
||||||
|
declare char
|
||||||
|
declare isquote
|
||||||
|
declare isnotquote
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "skipchar("
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
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 "emit"
|
||||||
|
if iscall
|
||||||
|
parsestatemit indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "trace"
|
||||||
|
if iscall
|
||||||
|
parsestattrace indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "skipchar"
|
||||||
|
if iscall
|
||||||
|
parsestatskipchar 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 "char * "
|
||||||
|
emit funcname
|
||||||
|
emit "("
|
||||||
|
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 ", "
|
||||||
|
/
|
||||||
|
emit "char * var_"
|
||||||
|
emit var
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
skipchar "/"
|
||||||
|
skipchar eol
|
||||||
|
emit ");"
|
||||||
|
emit "\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
skipchar ":"
|
||||||
|
skipchar eol
|
||||||
|
emit ")\n{\n"
|
||||||
|
parseblock " "
|
||||||
|
emit "}\n\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitheader:
|
||||||
|
emit "#include <assert.h>\n"
|
||||||
|
emit "#include <stdio.h>\n"
|
||||||
|
emit "#include <stdlib.h>\n"
|
||||||
|
emit "#include <string.h>\n"
|
||||||
|
emit eol
|
||||||
|
emit eol
|
||||||
|
emit "char var_eof[2] = {-1, 0};\n"
|
||||||
|
emit "char var_eol[2] = {10, 0};\n"
|
||||||
|
emit "char var_quote[2] = {34, 0};\n"
|
||||||
|
emit "char var_false[1] = {0};\n"
|
||||||
|
emit "char var_true[2] = {'1', 0};\n"
|
||||||
|
emit eol
|
||||||
|
emit eol
|
||||||
|
emit "char * eq(char * a, char * b)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " return (strcmp(a, b) == 0) ? var_true : var_false;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "char * lt(char * a, char * b)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " return (strcmp(a, b) < 0) ? var_true : var_false;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "char * not(char * a)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " return (strcmp(a, var_true) != 0) ? var_true : var_false;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "char * addstringchar(char * str, char * chr)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " int str_len = strlen(str);\n"
|
||||||
|
emit " assert(strlen(chr) == 1);\n"
|
||||||
|
emit " char * res = malloc((str_len + 2) * sizeof(char));\n"
|
||||||
|
emit " strcpy(res, str);\n"
|
||||||
|
emit " res[str_len + 0] = chr[0];\n"
|
||||||
|
emit " res[str_len + 1] = 0;\n"
|
||||||
|
emit " return res;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "char * emit(char * str)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " fputs(str, stdout);\n"
|
||||||
|
emit " return 0;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "char * trace(char * var_name, char * var_value)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " const char * env_trace = getenv("
|
||||||
|
emit quote
|
||||||
|
emit "TRACE"
|
||||||
|
emit quote
|
||||||
|
emit ");\n"
|
||||||
|
emit " if( !env_trace ) return 0;\n"
|
||||||
|
emit " fputs(var_name, stderr);\n"
|
||||||
|
emit " fputs("
|
||||||
|
emit quote
|
||||||
|
emit "="
|
||||||
|
emit quote
|
||||||
|
emit ", stderr);\n"
|
||||||
|
emit " fputs(var_value, stderr);\n"
|
||||||
|
emit " fputs(var_eol, stderr);\n"
|
||||||
|
emit " return 0;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit eol
|
||||||
|
emit "int LINE = 1;\n"
|
||||||
|
emit eol
|
||||||
|
emit "char * peek()\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " char * res = malloc(2*sizeof(char));\n"
|
||||||
|
emit " res[0] = getc(stdin);\n"
|
||||||
|
emit " res[1] = 0;\n"
|
||||||
|
emit " ungetc(res[0], stdin);\n"
|
||||||
|
emit " return res;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "void skip()\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " char c = getc(stdin);\n"
|
||||||
|
emit " if( c == 10 ) LINE += 1;\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "void skipchar(char * chr)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit " assert(strlen(chr) == 1);\n"
|
||||||
|
emit " char * act = peek();\n"
|
||||||
|
emit " assert(strlen(act) == 1);\n"
|
||||||
|
emit " if( chr[0] == act[0] ) {skip(); return;};\n"
|
||||||
|
emit " fprintf(stderr, "
|
||||||
|
emit quote
|
||||||
|
emit "Expected '%c' on line %d but saw '%c' instead%c"
|
||||||
|
emit quote
|
||||||
|
emit ", chr[0], LINE, act[0], 10);\n"
|
||||||
|
emit " exit(1);\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitfooter:
|
||||||
|
emit ""
|
||||||
|
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
|
||||||
|
/
|
||||||
2162
t-diagram.excalidraw
Normal file
2162
t-diagram.excalidraw
Normal file
File diff suppressed because it is too large
Load Diff
BIN
t-diagram.png
Normal file
BIN
t-diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
Loading…
x
Reference in New Issue
Block a user