Updated llvm with other changes

Started on outputting string constants

Need to:
- Calc string length
- Implement _add (including allocation)
- Everything else
This commit is contained in:
Johan B.W. de Vries 2026-01-18 13:11:17 +01:00
parent cfae563aef
commit 098ab080ca
2 changed files with 344 additions and 65 deletions

View File

@ -18,10 +18,10 @@ lang0ll0.c: lang0ll.lang0 $(LANG0C)
cat $< | $(LANG0C) > $@ cat $< | $(LANG0C) > $@
lang0ll0.o: lang0ll0.c lang0ll0.o: lang0ll0.c
gcc -c $< gcc -g -c $<
lang0ll0.exe: lang0ll0.o lang0ll0.exe: lang0ll0.o
gcc -o $@ $< gcc -g -o $@ $<
lang0ll1.ll: lang0ll.lang0 lang0ll0.exe lang0ll1.ll: lang0ll.lang0 lang0ll0.exe
cat $< | ./lang0ll0.exe > $@ cat $< | ./lang0ll0.exe > $@
@ -39,4 +39,4 @@ foo.ll: foo.c
clang -S -emit-llvm $^ clang -S -emit-llvm $^
clean: clean:
rm -f lang0ll*.py lang0ll*.ll lang0ll*.o lang0ll*.exe foo.ll foo.o foo.exe rm -f lang0ll*.c lang0ll*.ll lang0ll*.o lang0ll*.exe foo.ll foo.o foo.exe

View File

@ -1,9 +1,20 @@
increaseindent indent: registerid id:
calc indent addstringchar indent " " declare idname
calc indent addstringchar indent " " declare newidx
calc indent addstringchar indent " "
calc indent addstringchar indent " " calc idname mapgetkey "REGISTERID" id ""
return indent if idname
return idname
/
declare idnamea
calc idnamea add "id_" id
return idnamea
/
emitln data:
emit data
emit eol
/ /
lexident: lexident:
@ -22,16 +33,34 @@ lexident:
if isafterz if isafterz
break break
/ /
calc word addstringchar word char calc word add word char
skip skip
/ /
return word return word
/ /
skipchar exp:
declare act
declare lineno
declare colno
calc act peek
calc lineno stdinlineno
calc colno stdincolno
check eq exp act : "Unexpected character" act "expected" exp "at" lineno colno
skip
/
increaseindent indent:
calc indent add indent " "
return indent
/
parseconststring: parseconststring:
declare char declare char
declare iseof declare iseof
declare isquote declare isquote
declare str
set str ""
skipchar quote skipchar quote
forever forever
calc char peek calc char peek
@ -43,24 +72,43 @@ parseconststring:
if isquote if isquote
break break
/ /
calc str add str char
skip skip
/ /
skipchar quote skipchar quote
emit "i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0)"
declare constid
calc constid mapgetkey "stringconst" str ""
declare isempty
calc isempty eq constid ""
if isempty
calc constid mapgetkey "stringconst" "___count___" "0"
calc constid add constid "1"
mapsetkey "stringconst" "___count___" constid
/
mapsetkey "stringconst" str constid
mapsetkey "stringconst" constid str
emit "i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str."
emit constid
emit ", i64 0, i64 0)"
return return
/ /
parseexprvarref: parseexprvarref:
declare varid
declare varname declare varname
calc varname lexident calc varname lexident
calc varid registerid varname
emit "i8* %" emit "i8* %"
emit varname emit varid
return return
/ /
parseexprcall: parseexprcall:
declare char declare char
declare first declare first
declare funcid
declare funcname declare funcname
declare isspace declare isspace
declare isnotspace declare isnotspace
@ -69,7 +117,9 @@ parseexprcall:
declare isquote declare isquote
declare isnotquote declare isnotquote
calc funcname lexident calc funcname lexident
emit funcname check mapgetkey "FUNCREG" funcname "" : "Function" funcname "does not exist"
calc funcid registerid funcname
emit funcid
emit "(" emit "("
set first "1" set first "1"
forever forever
@ -101,26 +151,23 @@ parseexprcall:
/ /
parsestatdeclare indent: parsestatdeclare indent:
declare var declare varid
declare varname
skipchar " " skipchar " "
calc var lexident calc varname lexident
emit indent
emit "char * var_"
emit var
emit ";"
emit eol
skipchar eol skipchar eol
return return
/ /
parsestatset indent: parsestatset indent:
declare var declare varid
declare varname
skipchar " " skipchar " "
calc var lexident calc varname lexident
calc varid registerid varname
skipchar " " skipchar " "
emit indent emit indent
emit "var_" emit varid
emit var
emit " = " emit " = "
parseconststring parseconststring
emit ";" emit ";"
@ -130,19 +177,19 @@ parsestatset indent:
/ /
parsestatcalc indent: parsestatcalc indent:
declare var declare varid
declare varname
declare varidx declare varidx
skipchar " " skipchar " "
calc var lexident calc varname lexident
calc varid registerid varname
skipchar " " skipchar " "
emit indent emit indent
emit "%" emit "%"
emit var emit varid
calc varidx mapgetkey "funcvarused" var calc varidx mapgetkey "funcvarused" varid ""
calc varidx intinc varidx calc varidx add varidx "1"
mapsetkey "funcvarused" var varidx mapsetkey "funcvarused" varid varidx
emit "."
emit varidx
emit " = call i8* @" emit " = call i8* @"
parseexprcall parseexprcall
emit ";" emit ";"
@ -154,39 +201,85 @@ parsestatcalc indent:
parseblock indent/ parseblock indent/
parsestatif indent: parsestatif indent:
declare indentt
skipchar " " skipchar " "
declare strlenvar
calc strlenvar mapgetkey "localvarused" "" ""
calc strlenvar add strlenvar "1"
mapsetkey "localvarused" "" strlenvar
trace strlenvar
emit indent emit indent
emit "if ( 0 < strlen(" emit "%"
emit strlenvar
emit " = call i64 @__strlen("
parseexprvarref parseexprvarref
emit ") )\n"
emit indent
emit "{\n"
skipchar eol skipchar eol
emitln ")"
declare strnotemptyvar
calc strnotemptyvar mapgetkey "localvarused" "" ""
calc strnotemptyvar add strnotemptyvar "1"
mapsetkey "localvarused" "" strnotemptyvar
trace strnotemptyvar
emit indent
emit "%"
emit strnotemptyvar
emit " = icmp ne i64 %"
emit strlenvar
emitln ", 0"
declare labelnotempty
calc labelnotempty mapgetkey "locallabelused" "" ""
calc labelnotempty add labelnotempty "1"
mapsetkey "locallabelused" "" labelnotempty
trace labelnotempty
declare labelempty
calc labelempty mapgetkey "locallabelused" "" ""
calc labelempty add labelempty "1"
mapsetkey "locallabelused" "" labelempty
trace labelempty
emit indent
emit "br i1 %"
emit strnotemptyvar
emit ", label %lbl"
emit labelnotempty
emit ", label %lbl"
emitln labelempty
emit "lbl"
emit labelnotempty
emitln ":"
declare indentt
calc indentt increaseindent indent calc indentt increaseindent indent
parseblock indentt parseblock indentt
emit indent
emit "}\n" emit "lbl"
emit labelempty
emitln ":"
return return
/ /
parsestatforever indent: parsestatforever indent:
declare indentt declare indentt
emit indent emit indent
emit "while (1)\n" emitln "while (1)"
emit indent emit indent
emit "{\n" emitln "{"
skipchar eol skipchar eol
calc indentt increaseindent indent calc indentt increaseindent indent
parseblock indentt parseblock indentt
emit indent emit indent
emit "}\n" emitln "}"
return return
/ /
parsestatbreak indent: parsestatbreak indent:
emit indent emit indent
emit "break;\n" emitln "break;"
skipchar eol skipchar eol
return return
/ /
@ -194,6 +287,8 @@ parsestatbreak indent:
parsestatreturn indent: parsestatreturn indent:
declare char declare char
declare isspace declare isspace
declare isnotquote
declare isquote
declare isnotspace declare isnotspace
emit indent emit indent
emit "ret " emit "ret "
@ -202,7 +297,15 @@ parsestatreturn indent:
calc isnotspace not isspace calc isnotspace not isspace
if isspace if isspace
skip skip
parseexprvarref calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
/ /
if isnotspace if isnotspace
emit "i18* 0" emit "i18* 0"
@ -213,24 +316,130 @@ parsestatreturn indent:
return return
/ /
parsestatcheck indent:
declare char
declare funcid
declare funcname
declare iscolon
declare iseol
declare isnotquote
declare isquote
declare notfirst
skipchar " "
emit indent
emit "if( 0 == strlen("
calc funcname lexident
calc funcid registerid funcname
emit funcid
emit "("
set notfirst ""
forever
skipchar " "
calc char peek
calc iscolon eq char ":"
if iscolon
break
/
if notfirst
emit ", "
/
calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
set notfirst "1"
/
skipchar ":"
emitln ")) )"
emit indent
emitln "{"
emit indent
emit " fprintf(stderr, "
emit quote
emit "%s"
emit quote
emit ", "
emit quote
emit "ERROR:"
emit quote
emitln ");"
forever
skipchar " "
emit indent
emit " fprintf(stderr, "
emit quote
emit " %s"
emit quote
emit ", "
calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
emitln ");"
calc char peek
calc iseol eq char eol
if iseol
break
/
/
emit indent
emit " fprintf(stderr, "
emit quote
emit "%s"
emit quote
emit ", __EOL"
emitln ");"
emit indent
emitln " exit(1);"
emit indent
emitln "}"
/
parsestattrace indent: parsestattrace indent:
declare varid
declare varname declare varname
emit indent emit indent
emit "trace(" emit "__trace("
emit quote emit quote
skipchar " " skipchar " "
calc varname lexident calc varname lexident
calc varid registerid varname
emit varname emit varname
emit quote emit quote
emit ", var_" emit ", "
emit varname emit varid
emit ");\n" emitln ");"
skipchar eol skipchar eol
return return
/ /
parsestat indent: parsestat indent:
declare call declare call
declare callid
declare char declare char
declare first declare first
declare iscall declare iscall
@ -277,13 +486,20 @@ parsestat indent:
parsestatreturn indent parsestatreturn indent
return return
/ /
calc iscall eq call "check"
if iscall
parsestatcheck indent
return
/
calc iscall eq call "trace" calc iscall eq call "trace"
if iscall if iscall
parsestattrace indent parsestattrace indent
return return
/ /
check mapgetkey "FUNCREG" call "" : "Function" call "does not exist"
calc callid registerid call
emit indent emit indent
emit call emit callid
emit "(" emit "("
set first "1" set first "1"
forever forever
@ -297,21 +513,21 @@ parsestat indent:
calc char peek calc char peek
calc isquote eq char quote calc isquote eq char quote
calc isnotquote not isquote calc isnotquote not isquote
calc isfirst eq first "1"
calc isnotfirst not isfirst
if isnotfirst
emit ", "
/
if isquote if isquote
parseconststring parseconststring
/ /
if isnotquote if isnotquote
parseexprvarref parseexprvarref
/ /
calc isfirst eq first "1"
calc isnotfirst not isfirst
if isnotfirst
emit ", "
/
set first "0" set first "0"
/ /
skipchar eol skipchar eol
emit ");\n" emitln ");"
return return
/ /
@ -357,15 +573,20 @@ parseblock indent:
parsefunc: parsefunc:
declare char declare char
declare first declare first
declare funcid
declare funcname declare funcname
declare iseoblock declare iseoblock
declare isfirst declare isfirst
declare ismain
declare isnotmain
declare isspace declare isspace
declare isnotfirst declare isnotfirst
declare isnotspace declare isnotspace
declare var declare varid
mapclear "funcvarused" declare varname
calc funcname lexident calc funcname lexident
mapsetkey "FUNCREG" funcname "1"
calc funcid registerid funcname
trace funcname trace funcname
emit "define i8* @" emit "define i8* @"
emit funcname emit funcname
@ -379,16 +600,16 @@ parsefunc:
break break
/ /
skip skip
calc var lexident calc varname lexident
calc varid registerid varname
calc isfirst eq first "1" calc isfirst eq first "1"
calc isnotfirst not isfirst calc isnotfirst not isfirst
if isnotfirst if isnotfirst
emit ", " emit ", "
/ /
emit "i8* %" emit "i8* %"
emit var emit varid
mapsetkey "funcvarused" "var" "0" mapsetkey "funcvarused" varid "0"
emit "_0"
set first "0" set first "0"
/ /
calc char peek calc char peek
@ -396,15 +617,16 @@ parsefunc:
if iseoblock if iseoblock
skipchar "/" skipchar "/"
skipchar eol skipchar eol
emit ");" emitln ");"
emit "\n"
return return
/ /
skipchar ":" skipchar ":"
skipchar eol skipchar eol
emit ")\n{\n" emitln ")"
emitln "{"
parseblock " " parseblock " "
emit "}\n\n" emitln "}"
emit eol
return return
/ /
@ -440,6 +662,32 @@ emitheader:
/ /
emitfooter: emitfooter:
declare constid
declare str
declare dontusethisstr
set dontusethisstr "__dontusethisstr__"
set constid "01"
forever
calc str mapgetkey "stringconst" constid dontusethisstr
declare unused
calc unused eq str dontusethisstr
if unused
break
/
emit "@str."
emit constid
emit " = internal constant [33 x i8] c"
emit quote
emit str
emitln quote
calc constid add constid "1"
/
emit "" emit ""
return return
/ /
@ -449,7 +697,38 @@ main:
declare iseof declare iseof
declare iseol declare iseol
declare isnoteol declare isnoteol
emitheader emitheader
mapsetkey "REGISTERID" "eof" "__EOF"
mapsetkey "REGISTERID" "eol" "__EOL"
mapsetkey "REGISTERID" "quote" "__QUOTE"
mapsetkey "FUNCREG" "add" "1"
mapsetkey "REGISTERID" "add" "__add"
mapsetkey "FUNCREG" "emit" "1"
mapsetkey "REGISTERID" "emit" "__emit"
mapsetkey "FUNCREG" "eq" "1"
mapsetkey "REGISTERID" "eq" "__eq"
mapsetkey "FUNCREG" "lt" "1"
mapsetkey "REGISTERID" "lt" "__lt"
mapsetkey "FUNCREG" "not" "1"
mapsetkey "REGISTERID" "not" "__not"
mapsetkey "FUNCREG" "mapclear" "1"
mapsetkey "REGISTERID" "mapclear" "__mapclear"
mapsetkey "FUNCREG" "mapgetkey" "1"
mapsetkey "REGISTERID" "mapgetkey" "__mapgetkey"
mapsetkey "FUNCREG" "mapsetkey" "1"
mapsetkey "REGISTERID" "mapsetkey" "__mapsetkey"
mapsetkey "FUNCREG" "peek" "1"
mapsetkey "REGISTERID" "peek" "__peek"
mapsetkey "FUNCREG" "skip" "1"
mapsetkey "REGISTERID" "skip" "__skip"
mapsetkey "FUNCREG" "stdincolno" "1"
mapsetkey "REGISTERID" "stdincolno" "__stdincolno"
mapsetkey "FUNCREG" "stdinlineno" "1"
mapsetkey "REGISTERID" "stdinlineno" "__stdinlineno"
forever forever
calc char peek calc char peek
calc iseof eq char eof calc iseof eq char eof