Idea
This commit is contained in:
parent
5939b7cba5
commit
3112636825
20
Makefile
20
Makefile
@ -1,17 +1,31 @@
|
||||
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 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-out3.py
|
||||
diff it1-out2.py it1-out3.py > it1-out3.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:
|
||||
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:
|
||||
-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