Idea
This commit is contained in:
parent
5939b7cba5
commit
3112636825
20
Makefile
20
Makefile
@ -1,17 +1,31 @@
|
|||||||
TEE :=
|
TEE :=
|
||||||
|
|
||||||
run:
|
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:
|
||||||
|
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
|
||||||
|
cat it2-in.lang0 | it2-out1 $(if $(TEE),| tee,> ) it2-out2.c && gcc it2-out2.c -o it2-out2
|
||||||
|
cat it2-in.lang0 | it2-out2 $(if $(TEE),| tee,> ) it2-out.c && gcc it2-out.c -o it2-out
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm it1-out*
|
-rm it1-out*
|
||||||
|
|
||||||
|
.PHONY: it2
|
||||||
|
|||||||
384
it2-in.lang0
Normal file
384
it2-in.lang0
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
increaseindent indent:
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
return indent
|
||||||
|
/
|
||||||
|
|
||||||
|
lexident:
|
||||||
|
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:
|
||||||
|
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
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprvarref:
|
||||||
|
calc varname lexident
|
||||||
|
emit "var_"
|
||||||
|
emit varname
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprcall:
|
||||||
|
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 ")"
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatset indent:
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "char * var_"
|
||||||
|
emit var
|
||||||
|
emit " = "
|
||||||
|
parseconststring
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatcalc indent:
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "char * var_"
|
||||||
|
emit var
|
||||||
|
emit " = "
|
||||||
|
parseexprcall
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatif indent:
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "if ("
|
||||||
|
parseexprvarref
|
||||||
|
emit ")\n"
|
||||||
|
emit indent
|
||||||
|
emit "{\n"
|
||||||
|
skipchar eol
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "}\n"
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatforever indent:
|
||||||
|
emit indent
|
||||||
|
emit "while (1)\n"
|
||||||
|
emit indent
|
||||||
|
emit "{\n"
|
||||||
|
skipchar eol
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "}\n"
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatbreak indent:
|
||||||
|
emit indent
|
||||||
|
emit "break;\n"
|
||||||
|
skipchar eol
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatreturn indent:
|
||||||
|
emit indent
|
||||||
|
emit "return "
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
if isspace
|
||||||
|
skip
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatemit indent:
|
||||||
|
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
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestattrace indent:
|
||||||
|
emit indent
|
||||||
|
emit "trace("
|
||||||
|
emit quote
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
emit varname
|
||||||
|
emit quote
|
||||||
|
emit ", "
|
||||||
|
emit varname
|
||||||
|
emit ")\n"
|
||||||
|
skipchar eol
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatskipchar indent:
|
||||||
|
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
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestat indent:
|
||||||
|
calc call lexident
|
||||||
|
trace call
|
||||||
|
calc isset eq call "set"
|
||||||
|
if isset
|
||||||
|
parsestatset indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscalc eq call "calc"
|
||||||
|
if iscalc
|
||||||
|
parsestatcalc indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc isif eq call "if"
|
||||||
|
if isif
|
||||||
|
parsestatif indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc isforever eq call "forever"
|
||||||
|
if isforever
|
||||||
|
parsestatforever indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc isbreak eq call "break"
|
||||||
|
if isbreak
|
||||||
|
parsestatbreak indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc isreturn eq call "return"
|
||||||
|
if isreturn
|
||||||
|
parsestatreturn indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc isemit eq call "emit"
|
||||||
|
if isemit
|
||||||
|
parsestatemit indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc istrace eq call "trace"
|
||||||
|
if istrace
|
||||||
|
parsestattrace indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc isskipchar eq call "skipchar"
|
||||||
|
if isskipchar
|
||||||
|
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"
|
||||||
|
/
|
||||||
|
|
||||||
|
parseblock indent:
|
||||||
|
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
|
||||||
|
/
|
||||||
|
/
|
||||||
|
|
||||||
|
parsefunc:
|
||||||
|
calc funcname lexident
|
||||||
|
trace funcname
|
||||||
|
emit "void "
|
||||||
|
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"
|
||||||
|
/
|
||||||
|
skipchar ":"
|
||||||
|
skipchar eol
|
||||||
|
emit ")\n{\n"
|
||||||
|
parseblock " "
|
||||||
|
emit "}\n\n"
|
||||||
|
/
|
||||||
|
|
||||||
|
emitheader:
|
||||||
|
emit "char * addstringchar(char * str, char * chr)\n"
|
||||||
|
emit "{\n"
|
||||||
|
emit "}\n"
|
||||||
|
emit "\n"
|
||||||
|
emit "\n"
|
||||||
|
/
|
||||||
|
|
||||||
|
emitfooter:
|
||||||
|
emit ""
|
||||||
|
/
|
||||||
|
|
||||||
|
main:
|
||||||
|
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
|
||||||
|
/
|
||||||
372
it2-out0.py
Normal file
372
it2-out0.py
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def eq(a, b):
|
||||||
|
return a == b
|
||||||
|
|
||||||
|
def lt(a, b):
|
||||||
|
return a[0] < b[0]
|
||||||
|
|
||||||
|
def addstringchar(a, b):
|
||||||
|
return a + b[0]
|
||||||
|
|
||||||
|
def emit(string):
|
||||||
|
sys.stdout.write(string)
|
||||||
|
|
||||||
|
def trace(header, value):
|
||||||
|
if os.environ.get('TRACE'):
|
||||||
|
sys.stderr.write(f'{header}={value!r}\n')
|
||||||
|
|
||||||
|
eof = chr(0)
|
||||||
|
eol = chr(10)
|
||||||
|
quote = chr(34)
|
||||||
|
PEEK = None
|
||||||
|
LINE = 1
|
||||||
|
|
||||||
|
def peek():
|
||||||
|
global PEEK
|
||||||
|
if PEEK is None:
|
||||||
|
char = sys.stdin.read(1)
|
||||||
|
trace('char', char)
|
||||||
|
if not char:
|
||||||
|
PEEK = eof
|
||||||
|
else:
|
||||||
|
PEEK = char
|
||||||
|
return PEEK
|
||||||
|
|
||||||
|
def skip():
|
||||||
|
global LINE
|
||||||
|
global PEEK
|
||||||
|
if eol == PEEK:
|
||||||
|
LINE += 1
|
||||||
|
PEEK = None
|
||||||
|
|
||||||
|
def skipchar(char):
|
||||||
|
global LINE
|
||||||
|
assert char == peek(), (LINE, char, peek())
|
||||||
|
skip()
|
||||||
|
|
||||||
|
def increaseindent(indent):
|
||||||
|
indent = addstringchar(indent, " ")
|
||||||
|
indent = addstringchar(indent, " ")
|
||||||
|
indent = addstringchar(indent, " ")
|
||||||
|
indent = addstringchar(indent, " ")
|
||||||
|
return indent
|
||||||
|
|
||||||
|
def lexident():
|
||||||
|
word = ""
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
isbeforea = lt(char, "a")
|
||||||
|
if isbeforea:
|
||||||
|
break
|
||||||
|
isafterz = lt("z", char)
|
||||||
|
if isafterz:
|
||||||
|
break
|
||||||
|
word = addstringchar(word, char)
|
||||||
|
skip()
|
||||||
|
return word
|
||||||
|
|
||||||
|
def parseconststring():
|
||||||
|
skipchar(quote)
|
||||||
|
emit(quote)
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
iseof = eq(char, eof)
|
||||||
|
if iseof:
|
||||||
|
break
|
||||||
|
isquote = eq(char, quote)
|
||||||
|
if isquote:
|
||||||
|
break
|
||||||
|
emit(char)
|
||||||
|
skip()
|
||||||
|
skipchar(quote)
|
||||||
|
emit(quote)
|
||||||
|
|
||||||
|
def parseexprvarref():
|
||||||
|
varname = lexident()
|
||||||
|
emit("var_")
|
||||||
|
emit(varname)
|
||||||
|
|
||||||
|
def parseexprcall():
|
||||||
|
funcname = lexident()
|
||||||
|
emit(funcname)
|
||||||
|
emit("(")
|
||||||
|
first = "1"
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
isspace = eq(char, " ")
|
||||||
|
isnotspace = not(isspace)
|
||||||
|
if isnotspace:
|
||||||
|
break
|
||||||
|
skip()
|
||||||
|
isfirst = eq(first, "1")
|
||||||
|
isnotfirst = not(isfirst)
|
||||||
|
if isnotfirst:
|
||||||
|
emit(", ")
|
||||||
|
char = peek()
|
||||||
|
isquote = eq(char, quote)
|
||||||
|
isnotquote = not(isquote)
|
||||||
|
if isquote:
|
||||||
|
parseconststring()
|
||||||
|
if isnotquote:
|
||||||
|
parseexprvarref()
|
||||||
|
first = "0"
|
||||||
|
emit(")")
|
||||||
|
|
||||||
|
def parsestatset(indent):
|
||||||
|
skipchar(" ")
|
||||||
|
var = lexident()
|
||||||
|
skipchar(" ")
|
||||||
|
emit(indent)
|
||||||
|
emit("char * var_")
|
||||||
|
emit(var)
|
||||||
|
emit(" = ")
|
||||||
|
parseconststring()
|
||||||
|
emit(";")
|
||||||
|
emit(eol)
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestatcalc(indent):
|
||||||
|
skipchar(" ")
|
||||||
|
var = lexident()
|
||||||
|
skipchar(" ")
|
||||||
|
emit(indent)
|
||||||
|
emit("char * var_")
|
||||||
|
emit(var)
|
||||||
|
emit(" = ")
|
||||||
|
parseexprcall()
|
||||||
|
emit(";")
|
||||||
|
emit(eol)
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestatif(indent):
|
||||||
|
skipchar(" ")
|
||||||
|
emit(indent)
|
||||||
|
emit("if (")
|
||||||
|
parseexprvarref()
|
||||||
|
emit(")\n")
|
||||||
|
emit(indent)
|
||||||
|
emit("{\n")
|
||||||
|
skipchar(eol)
|
||||||
|
indentt = increaseindent(indent)
|
||||||
|
parseblock(indentt)
|
||||||
|
emit(indent)
|
||||||
|
emit("}\n")
|
||||||
|
|
||||||
|
def parsestatforever(indent):
|
||||||
|
emit(indent)
|
||||||
|
emit("while (1)\n")
|
||||||
|
emit(indent)
|
||||||
|
emit("{\n")
|
||||||
|
skipchar(eol)
|
||||||
|
indentt = increaseindent(indent)
|
||||||
|
parseblock(indentt)
|
||||||
|
emit(indent)
|
||||||
|
emit("}\n")
|
||||||
|
|
||||||
|
def parsestatbreak(indent):
|
||||||
|
emit(indent)
|
||||||
|
emit("break;\n")
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestatreturn(indent):
|
||||||
|
emit(indent)
|
||||||
|
emit("return ")
|
||||||
|
char = peek()
|
||||||
|
isspace = eq(char, " ")
|
||||||
|
if isspace:
|
||||||
|
skip()
|
||||||
|
parseexprvarref()
|
||||||
|
emit(";")
|
||||||
|
emit(eol)
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestatemit(indent):
|
||||||
|
emit(indent)
|
||||||
|
emit("emit(")
|
||||||
|
skipchar(" ")
|
||||||
|
char = peek()
|
||||||
|
isquote = eq(char, quote)
|
||||||
|
isnotquote = not(isquote)
|
||||||
|
if isquote:
|
||||||
|
parseconststring()
|
||||||
|
if isnotquote:
|
||||||
|
parseexprvarref()
|
||||||
|
emit(");\n")
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestattrace(indent):
|
||||||
|
emit(indent)
|
||||||
|
emit("trace(")
|
||||||
|
emit(quote)
|
||||||
|
skipchar(" ")
|
||||||
|
varname = lexident()
|
||||||
|
emit(varname)
|
||||||
|
emit(quote)
|
||||||
|
emit(", ")
|
||||||
|
emit(varname)
|
||||||
|
emit(")\n")
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestatskipchar(indent):
|
||||||
|
skipchar(" ")
|
||||||
|
emit(indent)
|
||||||
|
emit("skipchar(")
|
||||||
|
char = peek()
|
||||||
|
isquote = eq(char, quote)
|
||||||
|
isnotquote = not(isquote)
|
||||||
|
if isquote:
|
||||||
|
parseconststring()
|
||||||
|
if isnotquote:
|
||||||
|
parseexprvarref()
|
||||||
|
emit(");\n")
|
||||||
|
skipchar(eol)
|
||||||
|
|
||||||
|
def parsestat(indent):
|
||||||
|
call = lexident()
|
||||||
|
trace("call", call)
|
||||||
|
isset = eq(call, "set")
|
||||||
|
if isset:
|
||||||
|
parsestatset(indent)
|
||||||
|
return
|
||||||
|
iscalc = eq(call, "calc")
|
||||||
|
if iscalc:
|
||||||
|
parsestatcalc(indent)
|
||||||
|
return
|
||||||
|
isif = eq(call, "if")
|
||||||
|
if isif:
|
||||||
|
parsestatif(indent)
|
||||||
|
return
|
||||||
|
isforever = eq(call, "forever")
|
||||||
|
if isforever:
|
||||||
|
parsestatforever(indent)
|
||||||
|
return
|
||||||
|
isbreak = eq(call, "break")
|
||||||
|
if isbreak:
|
||||||
|
parsestatbreak(indent)
|
||||||
|
return
|
||||||
|
isreturn = eq(call, "return")
|
||||||
|
if isreturn:
|
||||||
|
parsestatreturn(indent)
|
||||||
|
return
|
||||||
|
isemit = eq(call, "emit")
|
||||||
|
if isemit:
|
||||||
|
parsestatemit(indent)
|
||||||
|
return
|
||||||
|
istrace = eq(call, "trace")
|
||||||
|
if istrace:
|
||||||
|
parsestattrace(indent)
|
||||||
|
return
|
||||||
|
isskipchar = eq(call, "skipchar")
|
||||||
|
if isskipchar:
|
||||||
|
parsestatskipchar(indent)
|
||||||
|
return
|
||||||
|
emit(indent)
|
||||||
|
emit(call)
|
||||||
|
emit("(")
|
||||||
|
first = "1"
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
isspace = eq(char, " ")
|
||||||
|
isnotspace = not(isspace)
|
||||||
|
if isnotspace:
|
||||||
|
break
|
||||||
|
skip()
|
||||||
|
char = peek()
|
||||||
|
isquote = eq(char, quote)
|
||||||
|
isnotquote = not(isquote)
|
||||||
|
if isquote:
|
||||||
|
parseconststring()
|
||||||
|
if isnotquote:
|
||||||
|
parseexprvarref()
|
||||||
|
isfirst = eq(first, "1")
|
||||||
|
isnotfirst = not(isfirst)
|
||||||
|
if isnotfirst:
|
||||||
|
emit(", ")
|
||||||
|
first = "0"
|
||||||
|
skipchar(eol)
|
||||||
|
emit(");\n")
|
||||||
|
|
||||||
|
def parseblock(indent):
|
||||||
|
while True:
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
iseol = eq(char, eol)
|
||||||
|
isnoteol = not(iseol)
|
||||||
|
if isnoteol:
|
||||||
|
break
|
||||||
|
skip()
|
||||||
|
copy = " "
|
||||||
|
while True:
|
||||||
|
isdone = eq(copy, indent)
|
||||||
|
if isdone:
|
||||||
|
break
|
||||||
|
skipchar("\t")
|
||||||
|
copy = increaseindent(copy)
|
||||||
|
char = peek()
|
||||||
|
iseoblock = eq(char, "/")
|
||||||
|
if iseoblock:
|
||||||
|
skip()
|
||||||
|
skipchar(eol)
|
||||||
|
break
|
||||||
|
skipchar("\t")
|
||||||
|
parsestat(indent)
|
||||||
|
|
||||||
|
def parsefunc():
|
||||||
|
funcname = lexident()
|
||||||
|
trace("funcname", funcname)
|
||||||
|
emit("void ")
|
||||||
|
emit(funcname)
|
||||||
|
emit("(")
|
||||||
|
first = "1"
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
isspace = eq(char, " ")
|
||||||
|
isnotspace = not(isspace)
|
||||||
|
if isnotspace:
|
||||||
|
break
|
||||||
|
skip()
|
||||||
|
var = lexident()
|
||||||
|
isfirst = eq(first, "1")
|
||||||
|
isnotfirst = not(isfirst)
|
||||||
|
if isnotfirst:
|
||||||
|
emit(", ")
|
||||||
|
emit("char * var_")
|
||||||
|
emit(var)
|
||||||
|
first = "0"
|
||||||
|
skipchar(":")
|
||||||
|
skipchar(eol)
|
||||||
|
emit(")\n{\n")
|
||||||
|
parseblock(" ")
|
||||||
|
emit("}\n\n")
|
||||||
|
|
||||||
|
def emitheader():
|
||||||
|
emit("char * addstringchar(char * str, char * chr)\n")
|
||||||
|
emit("{\n")
|
||||||
|
emit("}\n")
|
||||||
|
emit("\n")
|
||||||
|
emit("\n")
|
||||||
|
|
||||||
|
def emitfooter():
|
||||||
|
emit("")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
emitheader()
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
iseof = eq(char, eof)
|
||||||
|
if iseof:
|
||||||
|
break
|
||||||
|
while True:
|
||||||
|
char = peek()
|
||||||
|
iseol = eq(char, eol)
|
||||||
|
isnoteol = not(iseol)
|
||||||
|
if isnoteol:
|
||||||
|
break
|
||||||
|
skip()
|
||||||
|
parsefunc()
|
||||||
|
emitfooter()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
453
it2-out1.c
Normal file
453
it2-out1.c
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
char * addstringchar(char * str, char * chr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void increaseindent(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_indent = addstringchar(var_indent, " ");
|
||||||
|
char * var_indent = addstringchar(var_indent, " ");
|
||||||
|
char * var_indent = addstringchar(var_indent, " ");
|
||||||
|
char * var_indent = addstringchar(var_indent, " ");
|
||||||
|
return var_indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lexident()
|
||||||
|
{
|
||||||
|
char * var_word = "";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isbeforea = lt(var_char, "a");
|
||||||
|
if (var_isbeforea)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char * var_isafterz = lt("z", var_char);
|
||||||
|
if (var_isafterz)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char * var_word = addstringchar(var_word, var_char);
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
return var_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseconststring()
|
||||||
|
{
|
||||||
|
skipchar(var_quote);
|
||||||
|
emit(var_quote);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_iseof = eq(var_char, var_eof);
|
||||||
|
if (var_iseof)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char * var_isquote = eq(var_char, var_quote);
|
||||||
|
if (var_isquote)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
emit(var_char);
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
skipchar(var_quote);
|
||||||
|
emit(var_quote);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseexprvarref()
|
||||||
|
{
|
||||||
|
char * var_varname = lexident();
|
||||||
|
emit("var_");
|
||||||
|
emit(var_varname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseexprcall()
|
||||||
|
{
|
||||||
|
char * var_funcname = lexident();
|
||||||
|
emit(var_funcname);
|
||||||
|
emit("(");
|
||||||
|
char * var_first = "1";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isspace = eq(var_char, " ");
|
||||||
|
char * var_isnotspace = not(var_isspace);
|
||||||
|
if (var_isnotspace)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
char * var_isfirst = eq(var_first, "1");
|
||||||
|
char * var_isnotfirst = not(var_isfirst);
|
||||||
|
if (var_isnotfirst)
|
||||||
|
{
|
||||||
|
emit(", ");
|
||||||
|
}
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isquote = eq(var_char, var_quote);
|
||||||
|
char * var_isnotquote = not(var_isquote);
|
||||||
|
if (var_isquote)
|
||||||
|
{
|
||||||
|
parseconststring();
|
||||||
|
}
|
||||||
|
if (var_isnotquote)
|
||||||
|
{
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
char * var_first = "0";
|
||||||
|
}
|
||||||
|
emit(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatset(char * var_indent)
|
||||||
|
{
|
||||||
|
skipchar(" ");
|
||||||
|
char * var_var = lexident();
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("char * var_");
|
||||||
|
emit(var_var);
|
||||||
|
emit(" = ");
|
||||||
|
parseconststring();
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatcalc(char * var_indent)
|
||||||
|
{
|
||||||
|
skipchar(" ");
|
||||||
|
char * var_var = lexident();
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("char * var_");
|
||||||
|
emit(var_var);
|
||||||
|
emit(" = ");
|
||||||
|
parseexprcall();
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatif(char * var_indent)
|
||||||
|
{
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("if (");
|
||||||
|
parseexprvarref();
|
||||||
|
emit(")\n");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("{\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
char * var_indentt = increaseindent(var_indent);
|
||||||
|
parseblock(var_indentt);
|
||||||
|
emit(var_indent);
|
||||||
|
emit("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatforever(char * var_indent)
|
||||||
|
{
|
||||||
|
emit(var_indent);
|
||||||
|
emit("while (1)\n");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("{\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
char * var_indentt = increaseindent(var_indent);
|
||||||
|
parseblock(var_indentt);
|
||||||
|
emit(var_indent);
|
||||||
|
emit("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatbreak(char * var_indent)
|
||||||
|
{
|
||||||
|
emit(var_indent);
|
||||||
|
emit("break;\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatreturn(char * var_indent)
|
||||||
|
{
|
||||||
|
emit(var_indent);
|
||||||
|
emit("return ");
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isspace = eq(var_char, " ");
|
||||||
|
if (var_isspace)
|
||||||
|
{
|
||||||
|
skip();
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatemit(char * var_indent)
|
||||||
|
{
|
||||||
|
emit(var_indent);
|
||||||
|
emit("emit(");
|
||||||
|
skipchar(" ");
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isquote = eq(var_char, var_quote);
|
||||||
|
char * var_isnotquote = not(var_isquote);
|
||||||
|
if (var_isquote)
|
||||||
|
{
|
||||||
|
parseconststring();
|
||||||
|
}
|
||||||
|
if (var_isnotquote)
|
||||||
|
{
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
emit(");\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestattrace(char * var_indent)
|
||||||
|
{
|
||||||
|
emit(var_indent);
|
||||||
|
emit("trace(");
|
||||||
|
emit(var_quote);
|
||||||
|
skipchar(" ");
|
||||||
|
char * var_varname = lexident();
|
||||||
|
emit(var_varname);
|
||||||
|
emit(var_quote);
|
||||||
|
emit(", ");
|
||||||
|
emit(var_varname);
|
||||||
|
emit(")\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestatskipchar(char * var_indent)
|
||||||
|
{
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("skipchar(");
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isquote = eq(var_char, var_quote);
|
||||||
|
char * var_isnotquote = not(var_isquote);
|
||||||
|
if (var_isquote)
|
||||||
|
{
|
||||||
|
parseconststring();
|
||||||
|
}
|
||||||
|
if (var_isnotquote)
|
||||||
|
{
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
emit(");\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsestat(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_call = lexident();
|
||||||
|
trace("call", call)
|
||||||
|
char * var_isset = eq(var_call, "set");
|
||||||
|
if (var_isset)
|
||||||
|
{
|
||||||
|
parsestatset(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_iscalc = eq(var_call, "calc");
|
||||||
|
if (var_iscalc)
|
||||||
|
{
|
||||||
|
parsestatcalc(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_isif = eq(var_call, "if");
|
||||||
|
if (var_isif)
|
||||||
|
{
|
||||||
|
parsestatif(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_isforever = eq(var_call, "forever");
|
||||||
|
if (var_isforever)
|
||||||
|
{
|
||||||
|
parsestatforever(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_isbreak = eq(var_call, "break");
|
||||||
|
if (var_isbreak)
|
||||||
|
{
|
||||||
|
parsestatbreak(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_isreturn = eq(var_call, "return");
|
||||||
|
if (var_isreturn)
|
||||||
|
{
|
||||||
|
parsestatreturn(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_isemit = eq(var_call, "emit");
|
||||||
|
if (var_isemit)
|
||||||
|
{
|
||||||
|
parsestatemit(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_istrace = eq(var_call, "trace");
|
||||||
|
if (var_istrace)
|
||||||
|
{
|
||||||
|
parsestattrace(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
char * var_isskipchar = eq(var_call, "skipchar");
|
||||||
|
if (var_isskipchar)
|
||||||
|
{
|
||||||
|
parsestatskipchar(var_indent);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
emit(var_indent);
|
||||||
|
emit(var_call);
|
||||||
|
emit("(");
|
||||||
|
char * var_first = "1";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isspace = eq(var_char, " ");
|
||||||
|
char * var_isnotspace = not(var_isspace);
|
||||||
|
if (var_isnotspace)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isquote = eq(var_char, var_quote);
|
||||||
|
char * var_isnotquote = not(var_isquote);
|
||||||
|
if (var_isquote)
|
||||||
|
{
|
||||||
|
parseconststring();
|
||||||
|
}
|
||||||
|
if (var_isnotquote)
|
||||||
|
{
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
char * var_isfirst = eq(var_first, "1");
|
||||||
|
char * var_isnotfirst = not(var_isfirst);
|
||||||
|
if (var_isnotfirst)
|
||||||
|
{
|
||||||
|
emit(", ");
|
||||||
|
}
|
||||||
|
char * var_first = "0";
|
||||||
|
}
|
||||||
|
skipchar(var_eol);
|
||||||
|
emit(");\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseblock(char * var_indent)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_iseol = eq(var_char, var_eol);
|
||||||
|
char * var_isnoteol = not(var_iseol);
|
||||||
|
if (var_isnoteol)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
char * var_copy = " ";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_isdone = eq(var_copy, var_indent);
|
||||||
|
if (var_isdone)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skipchar("\t");
|
||||||
|
char * var_copy = increaseindent(var_copy);
|
||||||
|
}
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_iseoblock = eq(var_char, "/");
|
||||||
|
if (var_iseoblock)
|
||||||
|
{
|
||||||
|
skip();
|
||||||
|
skipchar(var_eol);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skipchar("\t");
|
||||||
|
parsestat(var_indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parsefunc()
|
||||||
|
{
|
||||||
|
char * var_funcname = lexident();
|
||||||
|
trace("funcname", funcname)
|
||||||
|
emit("void ");
|
||||||
|
emit(var_funcname);
|
||||||
|
emit("(");
|
||||||
|
char * var_first = "1";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_isspace = eq(var_char, " ");
|
||||||
|
char * var_isnotspace = not(var_isspace);
|
||||||
|
if (var_isnotspace)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
char * var_var = lexident();
|
||||||
|
char * var_isfirst = eq(var_first, "1");
|
||||||
|
char * var_isnotfirst = not(var_isfirst);
|
||||||
|
if (var_isnotfirst)
|
||||||
|
{
|
||||||
|
emit(", ");
|
||||||
|
}
|
||||||
|
emit("char * var_");
|
||||||
|
emit(var_var);
|
||||||
|
char * var_first = "0";
|
||||||
|
}
|
||||||
|
skipchar(":");
|
||||||
|
skipchar(var_eol);
|
||||||
|
emit(")\n{\n");
|
||||||
|
parseblock(" ");
|
||||||
|
emit("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitheader()
|
||||||
|
{
|
||||||
|
emit("char * addstringchar(char * str, char * chr)\n");
|
||||||
|
emit("{\n");
|
||||||
|
emit("}\n");
|
||||||
|
emit("\n");
|
||||||
|
emit("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitfooter()
|
||||||
|
{
|
||||||
|
emit("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
emitheader();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_iseof = eq(var_char, var_eof);
|
||||||
|
if (var_iseof)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char * var_char = peek();
|
||||||
|
char * var_iseol = eq(var_char, var_eol);
|
||||||
|
char * var_isnoteol = not(var_iseol);
|
||||||
|
if (var_isnoteol)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
parsefunc();
|
||||||
|
}
|
||||||
|
emitfooter();
|
||||||
|
}
|
||||||
|
|
||||||
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