Compare commits

...

4 Commits

Author SHA1 Message Date
Johan B.W. de Vries
68611b4df3 More work 2026-01-25 15:10:26 +01:00
Johan B.W. de Vries
49e1bf204f Adds backslash as a build in constant 2026-01-25 15:10:12 +01:00
Johan B.W. de Vries
5369c15e05 Adds intinc as a buildint function 2026-01-25 13:14:02 +01:00
Johan B.W. de Vries
a282292604 Adds strlen as a builtin function 2026-01-25 12:47:58 +01:00
17 changed files with 619 additions and 56 deletions

View File

@ -409,6 +409,7 @@ 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)")
@ -475,6 +476,12 @@ 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("")
@ -489,6 +496,7 @@ def main():
emitheader()
# Standard library constants
mapsetkey("REGISTERID", "backslash", "__BACKSLASH")
mapsetkey("REGISTERID", "eof", "__EOF")
mapsetkey("REGISTERID", "eol", "__EOL")
mapsetkey("REGISTERID", "quote", "__QUOTE")
@ -500,6 +508,8 @@ 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")
@ -518,6 +528,8 @@ 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():

View File

@ -472,6 +472,7 @@ 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)"
@ -534,6 +535,12 @@ 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 ""
/
@ -551,6 +558,7 @@ emitfooter:
main:
emitheader
mapsetkey "REGISTERID" "backslash" "__BACKSLASH"
mapsetkey "REGISTERID" "eof" "__EOF"
mapsetkey "REGISTERID" "eol" "__EOL"
mapsetkey "REGISTERID" "quote" "__QUOTE"
@ -561,6 +569,8 @@ 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"
@ -579,6 +589,8 @@ main:
mapsetkey "REGISTERID" "stdincolno" "__stdincolno"
mapsetkey "FUNCREG" "stdinlineno" "1"
mapsetkey "REGISTERID" "stdinlineno" "__stdinlineno"
mapsetkey "FUNCREG" "strlen" "1"
mapsetkey "REGISTERID" "strlen" "__strlen"
forever

View File

@ -574,6 +574,7 @@ 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};"
@ -798,6 +799,31 @@ 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
@ -824,6 +850,7 @@ main:
emitheader
mapsetkey "REGISTERID" "backslash" "__BACKSLASH"
mapsetkey "REGISTERID" "eof" "__EOF"
mapsetkey "REGISTERID" "eol" "__EOL"
mapsetkey "REGISTERID" "quote" "__QUOTE"
@ -834,6 +861,8 @@ 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"
@ -852,6 +881,8 @@ 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

View File

@ -1,4 +1,18 @@
registerid id:
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:
declare idname
declare newidx
@ -22,8 +36,8 @@ makelocalvar:
declare prevvar
declare newvar
declare result
calc prevvar mapgetkey "localvarused" "" ""
calc newvar add prevvar "1"
calc prevvar mapgetkey "localvarused" "" "0"
calc newvar intinc prevvar
mapsetkey "localvarused" "" newvar
calc result add "%tmp" newvar
return result
@ -33,8 +47,8 @@ makelocallabel:
declare prevlabel
declare newlabel
declare result
calc prevlabel mapgetkey "locallabelused" "" ""
calc newlabel add prevlabel "1"
calc prevlabel mapgetkey "locallabelused" "" "0"
calc newlabel intinc prevlabel
mapsetkey "locallabelused" "" newlabel
calc result add "lbl" newlabel
return result
@ -44,15 +58,15 @@ makestringconst str:
declare constid
declare isempty
calc constid mapgetkey "stringconst" str ""
calc constid mapgetkey "str_to_const_id" str ""
calc isempty eq constid ""
if isempty
calc constid mapgetkey "stringconst" "___count___" "0"
calc constid add constid "1"
mapsetkey "stringconst" "___count___" constid
calc constid mapgetkey "const_id_to_str" "___count___" "0"
calc constid intinc constid
mapsetkey "const_id_to_str" "___count___" constid
/
mapsetkey "stringconst" str constid
mapsetkey "stringconst" constid str
mapsetkey "str_to_const_id" str constid
mapsetkey "const_id_to_str" constid str
return constid
/
@ -130,7 +144,7 @@ parseexprvarref:
declare varid
declare varname
calc varname lexident
calc varid registerid varname
calc varid registervar varname
emit "i8* "
emit varid
return
@ -148,9 +162,9 @@ parseexprcall:
declare isquote
declare isnotquote
calc funcname lexident
calc funcid registerfunc funcname
check mapgetkey "FUNCREG" funcname "" : "Function" funcname "does not exist"
emit "@id_"
emit funcname
emit funcid
emit "("
set first "1"
forever
@ -188,7 +202,7 @@ parsestatdeclare indent:
calc varname lexident
skipchar eol
calc varid registerid varname
calc varid registervar varname
emit indent
emit varid
emitln " = alloca i8*"
@ -204,7 +218,7 @@ parsestatset indent:
skipchar " "
calc varname lexident
calc varid registerid varname
calc varid registervar varname
skipchar " "
emit indent
emit tmpvar
@ -233,7 +247,7 @@ parsestatcalc indent:
skipchar " "
calc varname lexident
calc varid registerid varname
calc varid registervar varname
skipchar " "
emit indent
emit tmpvar
@ -400,7 +414,7 @@ parsestatcheck indent:
skipchar " "
calc funcname lexident
calc funcid registerid funcname
calc funcid registerfunc funcname
emit indent
emit funcresvar
@ -464,7 +478,7 @@ parsestatcheck indent:
emit indent
emit " "
emit stderrvar
emitln " = load %FILE*, %FILE** @stderrvar"
emitln " = load %FILE*, %FILE** @stderr"
emit indent
emit " call i32 @fputs(i8* @str.ERROR, %FILE* "
@ -527,7 +541,7 @@ parsestattrace indent:
skipchar eol
calc callconstid makestringconst varname
calc varid registerid varname
calc varid registervar varname
emit indent
emit "call void @__trace(i8* @str."
@ -551,6 +565,7 @@ parsestat indent:
declare isnotspace
declare isnotquote
calc call lexident
calc callid registerfunc call
trace call
calc iscall eq call "declare"
if iscall
@ -599,8 +614,8 @@ parsestat indent:
/
check mapgetkey "FUNCREG" call "" : "Function" call "does not exist"
emit indent
emit "call i8* @id_"
emit call
emit "call i8* "
emit callid
emit "("
set first "1"
forever
@ -689,10 +704,11 @@ parsefunc:
declare varid
declare varname
calc funcname lexident
calc funcid registerfunc funcname
mapsetkey "FUNCREG" funcname "1"
trace funcname
emit "define i8* @id_"
emit funcname
emit "define i8* "
emit funcid
emit "("
set first "1"
forever
@ -704,7 +720,7 @@ parsefunc:
/
skip
calc varname lexident
calc varid registerid varname
calc varid registervar varname
calc isfirst eq first "1"
calc isnotfirst not isfirst
if isnotfirst
@ -727,6 +743,7 @@ parsefunc:
emitln ")"
emitln "{"
parseblock " "
emitln " ret i8* @__EOF"
emitln "}"
emit eol
return
@ -757,14 +774,51 @@ 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 "\\0A\\00"
emit backslash
emit "0A"
emit backslash
emit "00"
emitln quote
emit "@__QUOTE = internal constant [2 x i8] c"
emit quote
emit "\\22\\00"
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"
emitln quote
emit eol
@ -774,6 +828,75 @@ 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
@ -782,48 +905,58 @@ 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:\\00"
emit "ERROR:"
emit backslash
emit "00"
emit quote
emitln ""
emit "@str.EMPTY = internal constant [1 x i8] c"
emit quote
emit "\\00"
emit backslash
emit "00"
emit quote
emitln ""
set dontusethisstr "__dontusethisstr__"
set constid "01"
set constid "0"
calc maxconstid mapgetkey "const_id_to_str" "___count___" "0"
forever
calc str mapgetkey "stringconst" constid dontusethisstr
calc str mapgetkey "const_id_to_str" constid "0"
declare unused
calc unused eq str dontusethisstr
if unused
break
/
calc strlen strlen str
calc len strlen str
calc len intinc len
emit "@str."
emit constid
emit " = internal constant ["
emit strlen
emit len
emit " x i8] c"
emit quote
emit str
emit "\\00"
emit backslash
emit "00"
emitln quote
calc constid add constid "1"
calc done eq constid maxconstid
if done
break
/
calc constid intinc constid
/
emit ""
@ -838,6 +971,7 @@ main:
emitheader
mapsetkey "REGISTERID" "backslash" "@__BACKSLASH"
mapsetkey "REGISTERID" "eof" "@__EOF"
mapsetkey "REGISTERID" "eol" "@__EOL"
mapsetkey "REGISTERID" "quote" "@__QUOTE"
@ -866,6 +1000,10 @@ 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

272
3-lang0ll/runtimetest.ll Normal file
View File

@ -0,0 +1,272 @@
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"

View File

@ -2,10 +2,12 @@ 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

View File

@ -123,6 +123,10 @@ 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.
@ -155,6 +159,12 @@ 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.
@ -194,6 +204,10 @@ 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.

View File

@ -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
python3 generate-recipes.py Makefile.mk it0 it1 it2 it3
include Makefile.mk
@ -29,6 +29,10 @@ 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
@ -85,3 +89,19 @@ 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 $@

View File

@ -24,3 +24,11 @@
/*.it2.result
/*.it2.stderr
/*.it2.stdout
/*.it3
/*.it3.ll
/*.it3.cmperr
/*.it3.ll.tmp
/*.it3.o
/*.it3.result
/*.it3.stderr
/*.it3.stdout

View File

@ -6,6 +6,7 @@ STAGE0_MAP = {
'it0': '.py',
'it1': '.py',
'it2': '.c',
'it3': '.ll',
}
class Rule:

View File

@ -0,0 +1 @@
\

View File

@ -0,0 +1,3 @@
main:
emit backslash
/

View File

@ -1,14 +1,3 @@
func tst a b:
declare var
calc var add a b
emit a
emit " + "
emit b
emit " = "
emit var
emit eol
/
main:
declare var

View File

@ -0,0 +1,5 @@
0 + 1: 1
5 + 1: 6
9 + 1: 10
15 + 1: 16
99 + 1: 100

View File

@ -0,0 +1,28 @@
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
/

View File

@ -0,0 +1,4 @@
strlen()=0
strlen()=1
strlen()=1
strlen()=8

View File

@ -0,0 +1,23 @@
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
/