Compare commits
No commits in common. "68611b4df32d4c94bb4e5e0a2c24108b29db041f" and "1be24ef7714be753b6f19ca932d632581cd0eee5" have entirely different histories.
68611b4df3
...
1be24ef771
@ -409,7 +409,6 @@ def emitheader():
|
||||
emitln(" if os.environ.get('TRACE'):")
|
||||
emitln(" sys.stderr.write(f'{header}={value!r}\\n')")
|
||||
emitln("")
|
||||
emitln("__BACKSLASH = chr(0x5C)")
|
||||
emitln("__EOF = chr(0xFF)")
|
||||
emitln("__EOL = chr(10)")
|
||||
emitln("__QUOTE = chr(34)")
|
||||
@ -476,12 +475,6 @@ def emitheader():
|
||||
emitln(" sys.stderr.flush()")
|
||||
emitln(" exit(1)")
|
||||
emitln("")
|
||||
emitln("def __strlen(a: str) -> str:")
|
||||
emitln(" return str(len(a))")
|
||||
emitln("")
|
||||
emitln("def __intinc(a: str) -> str:")
|
||||
emitln(" return str(int(a) + 1)")
|
||||
emitln("")
|
||||
emitln("# ### END OF RUNTIME ### #")
|
||||
emitln("")
|
||||
|
||||
@ -496,7 +489,6 @@ def main():
|
||||
emitheader()
|
||||
|
||||
# Standard library constants
|
||||
mapsetkey("REGISTERID", "backslash", "__BACKSLASH")
|
||||
mapsetkey("REGISTERID", "eof", "__EOF")
|
||||
mapsetkey("REGISTERID", "eol", "__EOL")
|
||||
mapsetkey("REGISTERID", "quote", "__QUOTE")
|
||||
@ -508,8 +500,6 @@ def main():
|
||||
mapsetkey("REGISTERID", "emit", "__emit")
|
||||
mapsetkey("FUNCREG", "eq", "1")
|
||||
mapsetkey("REGISTERID", "eq", "__eq")
|
||||
mapsetkey("FUNCREG", "intinc", "1")
|
||||
mapsetkey("REGISTERID", "intinc", "__intinc")
|
||||
mapsetkey("FUNCREG", "lt", "1")
|
||||
mapsetkey("REGISTERID", "lt", "__lt")
|
||||
mapsetkey("FUNCREG", "not", "1")
|
||||
@ -528,8 +518,6 @@ def main():
|
||||
mapsetkey("REGISTERID", "stdincolno", "__stdincolno")
|
||||
mapsetkey("FUNCREG", "stdinlineno", "1")
|
||||
mapsetkey("REGISTERID", "stdinlineno", "__stdinlineno")
|
||||
mapsetkey("FUNCREG", "strlen", "1")
|
||||
mapsetkey("REGISTERID", "strlen", "__strlen")
|
||||
|
||||
while True:
|
||||
if eof == peek():
|
||||
|
||||
@ -472,7 +472,6 @@ emitheader:
|
||||
emitln " if os.environ.get('TRACE'):"
|
||||
emitln " sys.stderr.write(f'{header}={value!r}\\n')"
|
||||
emitln ""
|
||||
emitln "__BACKSLASH = chr(0x5C)"
|
||||
emitln "__EOF = chr(0xFF)"
|
||||
emitln "__EOL = chr(10)"
|
||||
emitln "__QUOTE = chr(34)"
|
||||
@ -535,12 +534,6 @@ emitheader:
|
||||
emitln " sys.stderr.flush()"
|
||||
emitln " exit(1)"
|
||||
emitln ""
|
||||
emitln "def __strlen(a: str) -> str:"
|
||||
emitln " return str(len(a))"
|
||||
emitln ""
|
||||
emitln "def __intinc(a: str) -> str:"
|
||||
emitln " return str(int(a) + 1)"
|
||||
emitln ""
|
||||
emitln "# ### END OF RUNTIME ### #"
|
||||
emitln ""
|
||||
/
|
||||
@ -558,7 +551,6 @@ emitfooter:
|
||||
main:
|
||||
emitheader
|
||||
|
||||
mapsetkey "REGISTERID" "backslash" "__BACKSLASH"
|
||||
mapsetkey "REGISTERID" "eof" "__EOF"
|
||||
mapsetkey "REGISTERID" "eol" "__EOL"
|
||||
mapsetkey "REGISTERID" "quote" "__QUOTE"
|
||||
@ -569,8 +561,6 @@ main:
|
||||
mapsetkey "REGISTERID" "emit" "__emit"
|
||||
mapsetkey "FUNCREG" "eq" "1"
|
||||
mapsetkey "REGISTERID" "eq" "__eq"
|
||||
mapsetkey "FUNCREG" "intinc" "1"
|
||||
mapsetkey "REGISTERID" "intinc" "__intinc"
|
||||
mapsetkey "FUNCREG" "lt" "1"
|
||||
mapsetkey "REGISTERID" "lt" "__lt"
|
||||
mapsetkey "FUNCREG" "not" "1"
|
||||
@ -589,8 +579,6 @@ main:
|
||||
mapsetkey "REGISTERID" "stdincolno" "__stdincolno"
|
||||
mapsetkey "FUNCREG" "stdinlineno" "1"
|
||||
mapsetkey "REGISTERID" "stdinlineno" "__stdinlineno"
|
||||
mapsetkey "FUNCREG" "strlen" "1"
|
||||
mapsetkey "REGISTERID" "strlen" "__strlen"
|
||||
|
||||
|
||||
forever
|
||||
|
||||
@ -574,7 +574,6 @@ emitheader:
|
||||
emitln "#include <string.h>"
|
||||
emitln ""
|
||||
emitln ""
|
||||
emitln "char __BACKSLASH[2] = {0x5C, 0};"
|
||||
emitln "char __EOF[2] = {0xFF, 0};"
|
||||
emitln "char __EOL[2] = {10, 0};"
|
||||
emitln "char __QUOTE[2] = {34, 0};"
|
||||
@ -799,31 +798,6 @@ emitheader:
|
||||
emitln ";"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * __strlen(char * inp)"
|
||||
emitln "{"
|
||||
emitln " char * buffer = malloc(20);"
|
||||
emitln " size_t len = strlen(inp);"
|
||||
emit " snprintf(buffer, 20, "
|
||||
emit quote
|
||||
emit "%zu"
|
||||
emit quote
|
||||
emitln ", len);"
|
||||
emitln " return buffer;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * __intinc(char * inp)"
|
||||
emitln "{"
|
||||
emitln " char * buffer = malloc(20);"
|
||||
emitln " char * endptr;"
|
||||
emitln " unsigned long long number = strtoull(inp, &endptr, 10);"
|
||||
emit " snprintf(buffer, 20, "
|
||||
emit quote
|
||||
emit "%llu"
|
||||
emit quote
|
||||
emitln ", number + 1);"
|
||||
emitln " return buffer;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "// ### END OF RUNTIME ### //"
|
||||
emitln ""
|
||||
return
|
||||
@ -850,7 +824,6 @@ main:
|
||||
|
||||
emitheader
|
||||
|
||||
mapsetkey "REGISTERID" "backslash" "__BACKSLASH"
|
||||
mapsetkey "REGISTERID" "eof" "__EOF"
|
||||
mapsetkey "REGISTERID" "eol" "__EOL"
|
||||
mapsetkey "REGISTERID" "quote" "__QUOTE"
|
||||
@ -861,8 +834,6 @@ main:
|
||||
mapsetkey "REGISTERID" "emit" "__emit"
|
||||
mapsetkey "FUNCREG" "eq" "1"
|
||||
mapsetkey "REGISTERID" "eq" "__eq"
|
||||
mapsetkey "FUNCREG" "intinc" "1"
|
||||
mapsetkey "REGISTERID" "intinc" "__intinc"
|
||||
mapsetkey "FUNCREG" "lt" "1"
|
||||
mapsetkey "REGISTERID" "lt" "__lt"
|
||||
mapsetkey "FUNCREG" "not" "1"
|
||||
@ -881,8 +852,6 @@ main:
|
||||
mapsetkey "REGISTERID" "stdincolno" "__stdincolno"
|
||||
mapsetkey "FUNCREG" "stdinlineno" "1"
|
||||
mapsetkey "REGISTERID" "stdinlineno" "__stdinlineno"
|
||||
mapsetkey "FUNCREG" "strlen" "1"
|
||||
mapsetkey "REGISTERID" "strlen" "__strlen"
|
||||
|
||||
forever
|
||||
calc char peek
|
||||
|
||||
@ -1,18 +1,4 @@
|
||||
registerfunc id:
|
||||
declare idname
|
||||
declare newidx
|
||||
|
||||
calc idname mapgetkey "REGISTERID" id ""
|
||||
if idname
|
||||
return idname
|
||||
/
|
||||
|
||||
declare idnamea
|
||||
calc idnamea add "@id_" id
|
||||
return idnamea
|
||||
/
|
||||
|
||||
registervar id:
|
||||
registerid id:
|
||||
declare idname
|
||||
declare newidx
|
||||
|
||||
@ -36,8 +22,8 @@ makelocalvar:
|
||||
declare prevvar
|
||||
declare newvar
|
||||
declare result
|
||||
calc prevvar mapgetkey "localvarused" "" "0"
|
||||
calc newvar intinc prevvar
|
||||
calc prevvar mapgetkey "localvarused" "" ""
|
||||
calc newvar add prevvar "1"
|
||||
mapsetkey "localvarused" "" newvar
|
||||
calc result add "%tmp" newvar
|
||||
return result
|
||||
@ -47,8 +33,8 @@ makelocallabel:
|
||||
declare prevlabel
|
||||
declare newlabel
|
||||
declare result
|
||||
calc prevlabel mapgetkey "locallabelused" "" "0"
|
||||
calc newlabel intinc prevlabel
|
||||
calc prevlabel mapgetkey "locallabelused" "" ""
|
||||
calc newlabel add prevlabel "1"
|
||||
mapsetkey "locallabelused" "" newlabel
|
||||
calc result add "lbl" newlabel
|
||||
return result
|
||||
@ -58,15 +44,15 @@ makestringconst str:
|
||||
declare constid
|
||||
declare isempty
|
||||
|
||||
calc constid mapgetkey "str_to_const_id" str ""
|
||||
calc constid mapgetkey "stringconst" str ""
|
||||
calc isempty eq constid ""
|
||||
if isempty
|
||||
calc constid mapgetkey "const_id_to_str" "___count___" "0"
|
||||
calc constid intinc constid
|
||||
mapsetkey "const_id_to_str" "___count___" constid
|
||||
calc constid mapgetkey "stringconst" "___count___" "0"
|
||||
calc constid add constid "1"
|
||||
mapsetkey "stringconst" "___count___" constid
|
||||
/
|
||||
mapsetkey "str_to_const_id" str constid
|
||||
mapsetkey "const_id_to_str" constid str
|
||||
mapsetkey "stringconst" str constid
|
||||
mapsetkey "stringconst" constid str
|
||||
|
||||
return constid
|
||||
/
|
||||
@ -144,7 +130,7 @@ parseexprvarref:
|
||||
declare varid
|
||||
declare varname
|
||||
calc varname lexident
|
||||
calc varid registervar varname
|
||||
calc varid registerid varname
|
||||
emit "i8* "
|
||||
emit varid
|
||||
return
|
||||
@ -162,9 +148,9 @@ parseexprcall:
|
||||
declare isquote
|
||||
declare isnotquote
|
||||
calc funcname lexident
|
||||
calc funcid registerfunc funcname
|
||||
check mapgetkey "FUNCREG" funcname "" : "Function" funcname "does not exist"
|
||||
emit funcid
|
||||
emit "@id_"
|
||||
emit funcname
|
||||
emit "("
|
||||
set first "1"
|
||||
forever
|
||||
@ -202,7 +188,7 @@ parsestatdeclare indent:
|
||||
calc varname lexident
|
||||
skipchar eol
|
||||
|
||||
calc varid registervar varname
|
||||
calc varid registerid varname
|
||||
emit indent
|
||||
emit varid
|
||||
emitln " = alloca i8*"
|
||||
@ -218,7 +204,7 @@ parsestatset indent:
|
||||
|
||||
skipchar " "
|
||||
calc varname lexident
|
||||
calc varid registervar varname
|
||||
calc varid registerid varname
|
||||
skipchar " "
|
||||
emit indent
|
||||
emit tmpvar
|
||||
@ -247,7 +233,7 @@ parsestatcalc indent:
|
||||
|
||||
skipchar " "
|
||||
calc varname lexident
|
||||
calc varid registervar varname
|
||||
calc varid registerid varname
|
||||
skipchar " "
|
||||
emit indent
|
||||
emit tmpvar
|
||||
@ -414,7 +400,7 @@ parsestatcheck indent:
|
||||
skipchar " "
|
||||
|
||||
calc funcname lexident
|
||||
calc funcid registerfunc funcname
|
||||
calc funcid registerid funcname
|
||||
|
||||
emit indent
|
||||
emit funcresvar
|
||||
@ -478,7 +464,7 @@ parsestatcheck indent:
|
||||
emit indent
|
||||
emit " "
|
||||
emit stderrvar
|
||||
emitln " = load %FILE*, %FILE** @stderr"
|
||||
emitln " = load %FILE*, %FILE** @stderrvar"
|
||||
|
||||
emit indent
|
||||
emit " call i32 @fputs(i8* @str.ERROR, %FILE* "
|
||||
@ -541,7 +527,7 @@ parsestattrace indent:
|
||||
skipchar eol
|
||||
|
||||
calc callconstid makestringconst varname
|
||||
calc varid registervar varname
|
||||
calc varid registerid varname
|
||||
|
||||
emit indent
|
||||
emit "call void @__trace(i8* @str."
|
||||
@ -565,7 +551,6 @@ parsestat indent:
|
||||
declare isnotspace
|
||||
declare isnotquote
|
||||
calc call lexident
|
||||
calc callid registerfunc call
|
||||
trace call
|
||||
calc iscall eq call "declare"
|
||||
if iscall
|
||||
@ -614,8 +599,8 @@ parsestat indent:
|
||||
/
|
||||
check mapgetkey "FUNCREG" call "" : "Function" call "does not exist"
|
||||
emit indent
|
||||
emit "call i8* "
|
||||
emit callid
|
||||
emit "call i8* @id_"
|
||||
emit call
|
||||
emit "("
|
||||
set first "1"
|
||||
forever
|
||||
@ -704,11 +689,10 @@ parsefunc:
|
||||
declare varid
|
||||
declare varname
|
||||
calc funcname lexident
|
||||
calc funcid registerfunc funcname
|
||||
mapsetkey "FUNCREG" funcname "1"
|
||||
trace funcname
|
||||
emit "define i8* "
|
||||
emit funcid
|
||||
emit "define i8* @id_"
|
||||
emit funcname
|
||||
emit "("
|
||||
set first "1"
|
||||
forever
|
||||
@ -720,7 +704,7 @@ parsefunc:
|
||||
/
|
||||
skip
|
||||
calc varname lexident
|
||||
calc varid registervar varname
|
||||
calc varid registerid varname
|
||||
calc isfirst eq first "1"
|
||||
calc isnotfirst not isfirst
|
||||
if isnotfirst
|
||||
@ -743,7 +727,6 @@ parsefunc:
|
||||
emitln ")"
|
||||
emitln "{"
|
||||
parseblock " "
|
||||
emitln " ret i8* @__EOF"
|
||||
emitln "}"
|
||||
emit eol
|
||||
return
|
||||
@ -774,51 +757,14 @@ emitheader:
|
||||
|
||||
emit eol
|
||||
|
||||
emit "@__BACKSLASH = internal constant [2 x i8] c"
|
||||
emit quote
|
||||
emit backslash
|
||||
emit backslash
|
||||
emit backslash
|
||||
emit "00"
|
||||
emit quote
|
||||
emitln ""
|
||||
|
||||
emit "@__EOF = internal constant [2 x i8] c"
|
||||
emit quote
|
||||
emit backslash
|
||||
emit backslash
|
||||
emit backslash
|
||||
emit "FF"
|
||||
emit quote
|
||||
emitln ""
|
||||
|
||||
emit "@__EOL = internal constant [2 x i8] c"
|
||||
emit quote
|
||||
emit backslash
|
||||
emit "0A"
|
||||
emit backslash
|
||||
emit "00"
|
||||
emit "\\0A\\00"
|
||||
emitln quote
|
||||
|
||||
emit "@__QUOTE = internal constant [2 x i8] c"
|
||||
emit quote
|
||||
emit backslash
|
||||
emit "22"
|
||||
emit backslash
|
||||
emit "00"
|
||||
emitln quote
|
||||
|
||||
emit "@__FALSE = internal constant [1 x i8] c"
|
||||
emit quote
|
||||
emit backslash
|
||||
emit "00"
|
||||
emitln quote
|
||||
|
||||
emit "@__TRUE = internal constant [2 x i8] c"
|
||||
emit quote
|
||||
emit "1"
|
||||
emit backslash
|
||||
emit "00"
|
||||
emit "\\22\\00"
|
||||
emitln quote
|
||||
|
||||
emit eol
|
||||
@ -828,75 +774,6 @@ emitheader:
|
||||
emitln " ret i8* %0"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__eq(i8* %0, i8* %1)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__lt(i8* %0, i8* %1)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__not(i8* %0)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__add(i8* %0, i8* %1)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__emit(i8* %0)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__trace(i8* %0)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__peek()"
|
||||
emitln "{"
|
||||
emitln " ret i8* @__EOL ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__skip()"
|
||||
emitln "{"
|
||||
emitln " ret i8* @__EOL ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__stdinlineno()"
|
||||
emitln "{"
|
||||
emitln " ret i8* @__EOL ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__stdincolno()"
|
||||
emitln "{"
|
||||
emitln " ret i8* @__EOL ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__mapgetkey(i8* %0, i8* %1, i8* %2)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__mapsetkey(i8* %0, i8* %1, i8* %2)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__strlen(i8* %0)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emitln "define i8* @__intinc(i8* %0)"
|
||||
emitln "{"
|
||||
emitln " ret i8* %0 ; STUB"
|
||||
emitln "}"
|
||||
|
||||
emit eol
|
||||
|
||||
@ -905,58 +782,48 @@ emitheader:
|
||||
|
||||
emitfooter:
|
||||
declare constid
|
||||
declare done
|
||||
declare len
|
||||
declare maxconstid
|
||||
declare str
|
||||
declare strlenvar
|
||||
declare dontusethisstr
|
||||
|
||||
emitln "define i64 @main() {"
|
||||
emitln " call i8* @id_main()"
|
||||
emitln " ret i64 0"
|
||||
emitln "}"
|
||||
|
||||
emit "@str.ERROR = internal constant [7 x i8] c"
|
||||
emit quote
|
||||
emit "ERROR:"
|
||||
emit backslash
|
||||
emit "00"
|
||||
emit "ERROR:\\00"
|
||||
emit quote
|
||||
emitln ""
|
||||
|
||||
emit "@str.EMPTY = internal constant [1 x i8] c"
|
||||
emit quote
|
||||
emit backslash
|
||||
emit "00"
|
||||
emit "\\00"
|
||||
emit quote
|
||||
emitln ""
|
||||
|
||||
set constid "0"
|
||||
calc maxconstid mapgetkey "const_id_to_str" "___count___" "0"
|
||||
forever
|
||||
calc str mapgetkey "const_id_to_str" constid "0"
|
||||
|
||||
calc len strlen str
|
||||
calc len intinc len
|
||||
set dontusethisstr "__dontusethisstr__"
|
||||
|
||||
set constid "01"
|
||||
forever
|
||||
calc str mapgetkey "stringconst" constid dontusethisstr
|
||||
|
||||
declare unused
|
||||
calc unused eq str dontusethisstr
|
||||
if unused
|
||||
break
|
||||
/
|
||||
|
||||
calc strlen strlen str
|
||||
|
||||
emit "@str."
|
||||
emit constid
|
||||
emit " = internal constant ["
|
||||
emit len
|
||||
emit strlen
|
||||
emit " x i8] c"
|
||||
emit quote
|
||||
emit str
|
||||
emit backslash
|
||||
emit "00"
|
||||
emit "\\00"
|
||||
emitln quote
|
||||
|
||||
calc done eq constid maxconstid
|
||||
if done
|
||||
break
|
||||
/
|
||||
|
||||
calc constid intinc constid
|
||||
calc constid add constid "1"
|
||||
/
|
||||
|
||||
emit ""
|
||||
@ -971,7 +838,6 @@ main:
|
||||
|
||||
emitheader
|
||||
|
||||
mapsetkey "REGISTERID" "backslash" "@__BACKSLASH"
|
||||
mapsetkey "REGISTERID" "eof" "@__EOF"
|
||||
mapsetkey "REGISTERID" "eol" "@__EOL"
|
||||
mapsetkey "REGISTERID" "quote" "@__QUOTE"
|
||||
@ -1000,10 +866,6 @@ main:
|
||||
mapsetkey "REGISTERID" "stdincolno" "@__stdincolno"
|
||||
mapsetkey "FUNCREG" "stdinlineno" "1"
|
||||
mapsetkey "REGISTERID" "stdinlineno" "@__stdinlineno"
|
||||
mapsetkey "FUNCREG" "strlen" "1"
|
||||
mapsetkey "REGISTERID" "strlen" "@__strlen"
|
||||
mapsetkey "FUNCREG" "intinc" "1"
|
||||
mapsetkey "REGISTERID" "intinc" "@__intinc"
|
||||
|
||||
forever
|
||||
calc char peek
|
||||
|
||||
@ -1,272 +0,0 @@
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-linux-gnu"
|
||||
|
||||
%FILE = type opaque
|
||||
@stdout = global %FILE* null
|
||||
|
||||
declare void @exit(i32)
|
||||
declare i32 @fputs(i8*, %FILE*)
|
||||
declare %FILE* @fdopen(i32, i8*)
|
||||
declare void @fclose(%FILE*)
|
||||
|
||||
@__BACKSLASH = internal constant [2 x i8] c"\\\00"
|
||||
@__EOF = internal constant [2 x i8] c"\\\FF"
|
||||
@__EOL = internal constant [2 x i8] c"\0A\00"
|
||||
@__QUOTE = internal constant [2 x i8] c"\22\00"
|
||||
@__FALSE = internal constant [1 x i8] c"\00"
|
||||
@__TRUE = internal constant [2 x i8] c"1\00"
|
||||
|
||||
define i8* @__drop_i8_type(i8* %0) alwaysinline readnone
|
||||
{
|
||||
ret i8* %0
|
||||
}
|
||||
define i8* @__eq(i8* %0, i8* %1)
|
||||
{
|
||||
%i = alloca i64, align 8
|
||||
|
||||
store i64 0, i64* %i
|
||||
br label %loop
|
||||
loop:
|
||||
%index = load i64, i64* %i
|
||||
%char0_adr = getelementptr i8, i8* %0, i64 %index
|
||||
%char1_adr = getelementptr i8, i8* %1, i64 %index
|
||||
|
||||
%char0 = load i8, i8* %char0_adr
|
||||
%char1 = load i8, i8* %char1_adr
|
||||
|
||||
%chars_differ = icmp ne i8 %char0, %char1
|
||||
br i1 %chars_differ, label %lbl_not_equal, label %lbl_equal
|
||||
lbl_equal:
|
||||
%string_end = icmp eq i8 %char0, 0
|
||||
br i1 %string_end, label %string_equal, label %next_char
|
||||
string_equal:
|
||||
ret i8* @__TRUE
|
||||
next_char:
|
||||
%next_index = add i64 %index, 1
|
||||
store i64 %next_index, i64* %i
|
||||
br label %loop
|
||||
|
||||
lbl_not_equal:
|
||||
ret i8* @__FALSE
|
||||
}
|
||||
define i8* @__lt(i8* %0, i8* %1)
|
||||
{
|
||||
%i = alloca i64, align 8
|
||||
|
||||
store i64 0, i64* %i
|
||||
br label %loop
|
||||
loop:
|
||||
%index = load i64, i64* %i
|
||||
%char0_adr = getelementptr i8, i8* %0, i64 %index
|
||||
%char1_adr = getelementptr i8, i8* %1, i64 %index
|
||||
|
||||
%char0 = load i8, i8* %char0_adr
|
||||
%char1 = load i8, i8* %char1_adr
|
||||
|
||||
%char0_eol = icmp eq i8 %char0, 0
|
||||
%char1_eol = icmp eq i8 %char1, 0
|
||||
|
||||
; if char0 == 0
|
||||
; if char1 == 0
|
||||
; return FALSE ; "" < "" === False
|
||||
; else
|
||||
; return TRUE ; "" < "." === True
|
||||
; endif
|
||||
; else
|
||||
; if char1 == 0
|
||||
; return FALSE ; "." < "" === False
|
||||
; else
|
||||
; if char0 < char1
|
||||
; return TRUE ; "a" < "b" === True
|
||||
; else
|
||||
; if char0 > char1
|
||||
; return FALSE ; "b" < "a" === False
|
||||
; else
|
||||
; jump next_char
|
||||
; endif
|
||||
; endif
|
||||
; endif
|
||||
; endif
|
||||
br i1 %char0_eol, label %lbl_char0_eol, label %lbl_char0_not_eol
|
||||
lbl_char0_eol:
|
||||
br i1 %char1_eol, label %lbl_not_smaller, label %lbl_smaller
|
||||
lbl_char0_not_eol:
|
||||
br i1 %char1_eol, label %lbl_not_smaller, label %lbl_char0_not_eol_char1_not_eol
|
||||
lbl_char0_not_eol_char1_not_eol:
|
||||
%char0_lt_char1 = icmp ult i8 %char0, %char1
|
||||
br i1 %char0_lt_char1, label %lbl_smaller, label %lbl_char0_ge_char1
|
||||
lbl_char0_ge_char1:
|
||||
%char0_gt_char1 = icmp ugt i8 %char0, %char1
|
||||
br i1 %char0_gt_char1, label %lbl_not_smaller, label %next_char
|
||||
next_char:
|
||||
%next_index = add i64 %index, 1
|
||||
store i64 %next_index, i64* %i
|
||||
br label %loop
|
||||
|
||||
lbl_smaller:
|
||||
ret i8* @__TRUE
|
||||
lbl_not_smaller:
|
||||
ret i8* @__FALSE
|
||||
}
|
||||
define i8* @__not(i8* %0)
|
||||
{
|
||||
%char0_adr = getelementptr i8, i8* %0, i64 0
|
||||
%char0 = load i8, i8* %char0_adr
|
||||
%char0_eol = icmp eq i8 %char0, 0
|
||||
br i1 %char0_eol, label %lbl_empty, label %lbl_not_empty
|
||||
lbl_empty:
|
||||
ret i8* @__TRUE;
|
||||
lbl_not_empty:
|
||||
ret i8* @__FALSE;
|
||||
}
|
||||
define i8* @__add(i8* %0, i8* %1)
|
||||
{
|
||||
ret i8* %0 ; STUB
|
||||
}
|
||||
define i8* @__emit(i8* %0)
|
||||
{
|
||||
%stdout_ptr = load %FILE*, %FILE** @stdout
|
||||
call i32 @fputs(i8* %0, %FILE* %stdout_ptr)
|
||||
ret i8* @__FALSE
|
||||
}
|
||||
define i8* @__trace(i8* %0, i8* %1)
|
||||
{
|
||||
ret i8* %0 ; STUB
|
||||
}
|
||||
define i8* @__peek()
|
||||
{
|
||||
ret i8* @__EOL ; STUB
|
||||
}
|
||||
define i8* @__skip()
|
||||
{
|
||||
ret i8* @__EOL ; STUB
|
||||
}
|
||||
define i8* @__stdinlineno()
|
||||
{
|
||||
ret i8* @__EOL ; STUB
|
||||
}
|
||||
define i8* @__stdincolno()
|
||||
{
|
||||
ret i8* @__EOL ; STUB
|
||||
}
|
||||
define i8* @__mapgetkey(i8* %0, i8* %1, i8* %2)
|
||||
{
|
||||
ret i8* %0 ; STUB
|
||||
}
|
||||
define i8* @__mapsetkey(i8* %0, i8* %1, i8* %2)
|
||||
{
|
||||
ret i8* %0 ; STUB
|
||||
}
|
||||
define i8* @__strlen(i8* %0)
|
||||
{
|
||||
ret i8* %0 ; STUB
|
||||
}
|
||||
define i8* @__intinc(i8* %0)
|
||||
{
|
||||
ret i8* %0 ; STUB
|
||||
}
|
||||
|
||||
|
||||
define void @test_result_1(i8* %func, i8* %arg0, i8* %result)
|
||||
{
|
||||
call i32 @__emit(i8* %func)
|
||||
call i32 @__emit(i8* @str.bracket)
|
||||
call i32 @__emit(i8* %arg0)
|
||||
call i32 @__emit(i8* @str.bracket_colon_space)
|
||||
call i32 @__emit(i8* %result)
|
||||
call i32 @__emit(i8* @__EOL)
|
||||
ret void
|
||||
}
|
||||
define void @test_result_2(i8* %func, i8* %arg0, i8* %arg1, i8* %result)
|
||||
{
|
||||
call i32 @__emit(i8* %func)
|
||||
call i32 @__emit(i8* @str.bracket)
|
||||
call i32 @__emit(i8* %arg0)
|
||||
call i32 @__emit(i8* @str.comma_space)
|
||||
call i32 @__emit(i8* %arg1)
|
||||
call i32 @__emit(i8* @str.bracket_colon_space)
|
||||
call i32 @__emit(i8* %result)
|
||||
call i32 @__emit(i8* @__EOL)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_eq(i8* %0, i8* %1)
|
||||
{
|
||||
%result = call i8* @__eq(i8* %0, i8* %1)
|
||||
call void @test_result_2(i8* @str.eq, i8* %0, i8* %1, i8* %result)
|
||||
ret void
|
||||
}
|
||||
define void @test_lt(i8* %0, i8* %1)
|
||||
{
|
||||
%result = call i8* @__lt(i8* %0, i8* %1)
|
||||
call void @test_result_2(i8* @str.lt, i8* %0, i8* %1, i8* %result)
|
||||
ret void
|
||||
}
|
||||
define void @test_not(i8* %0)
|
||||
{
|
||||
%result = call i8* @__not(i8* %0)
|
||||
call void @test_result_1(i8* @str.not, i8* %0, i8* %result)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define i64 @main()
|
||||
{
|
||||
%stdout_ptr = call %FILE* @fdopen(i32 1, i8* @str.w)
|
||||
store %FILE* %stdout_ptr, %FILE** @stdout
|
||||
|
||||
call void @test_eq(i8* @str., i8* @str.0)
|
||||
call void @test_eq(i8* @str.0, i8* @str.)
|
||||
call void @test_eq(i8* @str.0, i8* @str.0)
|
||||
call void @test_eq(i8* @str.a, i8* @str.a)
|
||||
call void @test_eq(i8* @str.a, i8* @str.b)
|
||||
call void @test_eq(i8* @str.a, i8* @str.c)
|
||||
call void @test_eq(i8* @str.b, i8* @str.a)
|
||||
call void @test_eq(i8* @str.b, i8* @str.b)
|
||||
call void @test_eq(i8* @str.b, i8* @str.c)
|
||||
call void @test_eq(i8* @str.c, i8* @str.a)
|
||||
call void @test_eq(i8* @str.c, i8* @str.b)
|
||||
call void @test_eq(i8* @str.c, i8* @str.c)
|
||||
call void @test_eq(i8* @str.left, i8* @str.right)
|
||||
call void @test_eq(i8* @str.left, i8* @str.left)
|
||||
call void @test_eq(i8* @str.right, i8* @str.left)
|
||||
call void @test_eq(i8* @str.right, i8* @str.right)
|
||||
|
||||
call void @test_lt(i8* @str.0, i8* @str.0)
|
||||
call void @test_lt(i8* @str.a, i8* @str.a)
|
||||
call void @test_lt(i8* @str.a, i8* @str.b)
|
||||
call void @test_lt(i8* @str.a, i8* @str.c)
|
||||
call void @test_lt(i8* @str.b, i8* @str.a)
|
||||
call void @test_lt(i8* @str.b, i8* @str.b)
|
||||
call void @test_lt(i8* @str.b, i8* @str.c)
|
||||
call void @test_lt(i8* @str.c, i8* @str.a)
|
||||
call void @test_lt(i8* @str.c, i8* @str.b)
|
||||
call void @test_lt(i8* @str.c, i8* @str.c)
|
||||
; `a` and `b` are expected to have length 1.
|
||||
|
||||
call void @test_not(i8* @str.)
|
||||
call void @test_not(i8* @str.0)
|
||||
call void @test_not(i8* @str.1)
|
||||
|
||||
|
||||
|
||||
call i32 @fclose(%FILE* %stdout_ptr)
|
||||
|
||||
ret i64 0
|
||||
}
|
||||
|
||||
@str. = internal constant [1 x i8] c"\00"
|
||||
@str.0 = internal constant [2 x i8] c"0\00"
|
||||
@str.1 = internal constant [2 x i8] c"1\00"
|
||||
@str.a = internal constant [2 x i8] c"a\00"
|
||||
@str.b = internal constant [2 x i8] c"b\00"
|
||||
@str.c = internal constant [2 x i8] c"c\00"
|
||||
@str.bracket = internal constant [2 x i8] c"(\00"
|
||||
@str.bracket_colon_space = internal constant [4 x i8] c"): \00"
|
||||
@str.comma_space = internal constant [3 x i8] c", \00"
|
||||
@str.eq = internal constant [3 x i8] c"eq\00"
|
||||
@str.left = internal constant [5 x i8] c"left\00"
|
||||
@str.lt = internal constant [3 x i8] c"lt\00"
|
||||
@str.not = internal constant [4 x i8] c"not\00"
|
||||
@str.right = internal constant [6 x i8] c"right\00"
|
||||
@str.w = internal constant [2 x i8] c"w\00"
|
||||
2
Makefile
2
Makefile
@ -2,12 +2,10 @@ all:
|
||||
$(MAKE) -C 0-lang0py all
|
||||
$(MAKE) -C 1-lang0py all
|
||||
$(MAKE) -C 2-lang0c all
|
||||
$(MAKE) -C 3-lang0ll all
|
||||
$(MAKE) -C tests all
|
||||
|
||||
clean:
|
||||
$(MAKE) -C 0-lang0py clean
|
||||
$(MAKE) -C 1-lang0py clean
|
||||
$(MAKE) -C 2-lang0c clean
|
||||
$(MAKE) -C 3-lang0ll clean
|
||||
$(MAKE) -C tests clean
|
||||
|
||||
14
README.md
14
README.md
@ -123,10 +123,6 @@ Writes the name and value of the variable passed to stderr if the TRACE environm
|
||||
|
||||
### Standard library constants
|
||||
|
||||
#### backslash
|
||||
|
||||
Backslash character.
|
||||
|
||||
#### eof
|
||||
|
||||
End of file character, zero byte.
|
||||
@ -159,12 +155,6 @@ Return true if the given strings are the same.
|
||||
|
||||
Return true if a would sort before b.
|
||||
|
||||
#### intinc
|
||||
|
||||
Assumes `a` is a string containing solely a decimal integer.
|
||||
|
||||
Returns a increased by one.
|
||||
|
||||
#### mapclear mapname
|
||||
|
||||
Maps are global and can be used from any function.
|
||||
@ -204,10 +194,6 @@ Returns the column number for stdin (starting at 1)
|
||||
|
||||
Returns the line number for stdin (starting at 1)
|
||||
|
||||
#### strlen a
|
||||
|
||||
Returns a string with the length of a.
|
||||
|
||||
### Typing
|
||||
|
||||
Every variable is of type string. Every function gets a number of strings as output, and returns another string.
|
||||
|
||||
@ -11,7 +11,7 @@ CFLAGS=-ggdb
|
||||
all: verify-results
|
||||
|
||||
Makefile.mk: generate-recipes.py $(wildcard test_*/test_*)
|
||||
python3 generate-recipes.py Makefile.mk it0 it1 it2 it3
|
||||
python3 generate-recipes.py Makefile.mk it0 it1 it2
|
||||
|
||||
include Makefile.mk
|
||||
|
||||
@ -29,10 +29,6 @@ clean:
|
||||
find build -name '*.it2.result' -delete
|
||||
find build -name '*.it2.stderr' -delete
|
||||
find build -name '*.it2.stdout' -delete
|
||||
find build -name '*.it3' -delete
|
||||
find build -name '*.it3.result' -delete
|
||||
find build -name '*.it3.stderr' -delete
|
||||
find build -name '*.it3.stdout' -delete
|
||||
find build -name '*.py' -delete
|
||||
find build -name '*.tmp' -delete
|
||||
|
||||
@ -89,19 +85,3 @@ build/%.it2.o: build/%.it2.c
|
||||
|
||||
build/%.it2: build/%.it2.o
|
||||
$(CC) $(CFLAGS) -o $@ $^ -lpython$(PYVERSION)
|
||||
|
||||
###
|
||||
# it3
|
||||
|
||||
../3-lang0ll/lang0ll.exe: ../0-lang0py/lang0py.exe ../1-lang0py/lang0py.exe ../2-lang0c/lang0c.exe ../3-lang0ll/lang0ll.lang0
|
||||
$(MAKE) -C ../3-lang0ll
|
||||
|
||||
build/%.it3.ll: %.lang0 ../3-lang0ll/lang0ll.exe
|
||||
-cat $< | ../3-lang0ll/lang0ll.exe > $@.tmp 2> build/$*.it3.cmperr
|
||||
mv $@.tmp $@
|
||||
|
||||
build/%.it3.s: build/%.it3.ll
|
||||
llc --relocation-model=pic $^
|
||||
|
||||
build/%.it3: build/%.it3.s
|
||||
clang $^ -o $@
|
||||
|
||||
8
tests/build/test_stdlib_functions/.gitignore
vendored
8
tests/build/test_stdlib_functions/.gitignore
vendored
@ -24,11 +24,3 @@
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
/*.it3
|
||||
/*.it3.ll
|
||||
/*.it3.cmperr
|
||||
/*.it3.ll.tmp
|
||||
/*.it3.o
|
||||
/*.it3.result
|
||||
/*.it3.stderr
|
||||
/*.it3.stdout
|
||||
|
||||
@ -6,7 +6,6 @@ STAGE0_MAP = {
|
||||
'it0': '.py',
|
||||
'it1': '.py',
|
||||
'it2': '.c',
|
||||
'it3': '.ll',
|
||||
}
|
||||
|
||||
class Rule:
|
||||
|
||||
@ -1 +0,0 @@
|
||||
\
|
||||
@ -1,3 +0,0 @@
|
||||
main:
|
||||
emit backslash
|
||||
/
|
||||
@ -1,3 +1,14 @@
|
||||
func tst a b:
|
||||
declare var
|
||||
calc var add a b
|
||||
emit a
|
||||
emit " + "
|
||||
emit b
|
||||
emit " = "
|
||||
emit var
|
||||
emit eol
|
||||
/
|
||||
|
||||
main:
|
||||
declare var
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
0 + 1: 1
|
||||
5 + 1: 6
|
||||
9 + 1: 10
|
||||
15 + 1: 16
|
||||
99 + 1: 100
|
||||
@ -1,28 +0,0 @@
|
||||
main:
|
||||
declare result
|
||||
|
||||
emit "0 + 1: "
|
||||
calc result intinc "0"
|
||||
emit result
|
||||
emit eol
|
||||
|
||||
emit "5 + 1: "
|
||||
calc result intinc "5"
|
||||
emit result
|
||||
emit eol
|
||||
|
||||
emit "9 + 1: "
|
||||
calc result intinc "9"
|
||||
emit result
|
||||
emit eol
|
||||
|
||||
emit "15 + 1: "
|
||||
calc result intinc "15"
|
||||
emit result
|
||||
emit eol
|
||||
|
||||
emit "99 + 1: "
|
||||
calc result intinc "99"
|
||||
emit result
|
||||
emit eol
|
||||
/
|
||||
@ -1,4 +0,0 @@
|
||||
strlen()=0
|
||||
strlen()=1
|
||||
strlen()=1
|
||||
strlen()=8
|
||||
@ -1,23 +0,0 @@
|
||||
main:
|
||||
declare var
|
||||
|
||||
calc var strlen ""
|
||||
emit "strlen()="
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var strlen "0"
|
||||
emit "strlen()="
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var strlen "1"
|
||||
emit "strlen()="
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var strlen "abcdefgh"
|
||||
emit "strlen()="
|
||||
emit var
|
||||
emit eol
|
||||
/
|
||||
Loading…
x
Reference in New Issue
Block a user