Compare commits
7 Commits
master
...
start-llvm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1be24ef771 | ||
|
|
449a89d6b3 | ||
|
|
c9029b1216 | ||
|
|
1671ce2285 | ||
|
|
098ab080ca | ||
|
|
cfae563aef | ||
|
|
8502abeff6 |
7
3-lang0ll/.gitignore
vendored
Normal file
7
3-lang0ll/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/lang0ll*.c
|
||||||
|
/lang0ll*.exe
|
||||||
|
/lang0ll*.ll
|
||||||
|
/lang0ll*.o
|
||||||
|
/lang0ll*.s
|
||||||
|
/foo.exe
|
||||||
|
/foo.ll
|
||||||
BIN
3-lang0ll/A Gentle Introduction to LLVM IR · mcyoung.pdf
Normal file
BIN
3-lang0ll/A Gentle Introduction to LLVM IR · mcyoung.pdf
Normal file
Binary file not shown.
45
3-lang0ll/Makefile
Normal file
45
3-lang0ll/Makefile
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LANG0C=$(CURDIR)/../2-lang0c/lang0c.exe
|
||||||
|
|
||||||
|
all: lang0ll.exe
|
||||||
|
|
||||||
|
%.exe: %.s
|
||||||
|
clang $^ -o $@
|
||||||
|
|
||||||
|
%.s: %.ll
|
||||||
|
llc --relocation-model=pic $^
|
||||||
|
|
||||||
|
lang0ll0.c: lang0ll.lang0 $(LANG0C)
|
||||||
|
cat $< | $(LANG0C) > $@
|
||||||
|
|
||||||
|
lang0ll0.o: lang0ll0.c
|
||||||
|
gcc -g -c $<
|
||||||
|
|
||||||
|
lang0ll0.exe: lang0ll0.o
|
||||||
|
gcc -g -o $@ $<
|
||||||
|
|
||||||
|
lang0ll1.ll: lang0ll.lang0 lang0ll0.exe
|
||||||
|
cat $< | ./lang0ll0.exe > $@
|
||||||
|
sed -i '/^.*; pre-declaration$$/d' $@
|
||||||
|
# Cannot diff on the first iteration - platform change
|
||||||
|
|
||||||
|
lang0ll2.ll: lang0ll.lang0 lang0ll1.exe
|
||||||
|
cat $< | ./lang0ll1.exe > $@
|
||||||
|
sed -i '/^.*; pre-declaration$$/d' $@
|
||||||
|
-diff lang0ll1.ll lang0ll2.ll
|
||||||
|
|
||||||
|
lang0ll.ll: lang0ll.lang0 lang0ll2.exe
|
||||||
|
cat $< | ./lang0ll2.exe > $@
|
||||||
|
sed -i '/^.*; pre-declaration$$/d' $@
|
||||||
|
-diff lang0ll2.ll lang0ll.ll
|
||||||
|
|
||||||
|
foo.ll: foo.c
|
||||||
|
clang -S -emit-llvm $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f lang0ll*.c lang0ll*.ll lang0ll*.o lang0ll*.exe foo.ll foo.o foo.exe
|
||||||
71
3-lang0ll/backup.ll
Normal file
71
3-lang0ll/backup.ll
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
declare noalias i8* @malloc(i64)
|
||||||
|
|
||||||
|
define i8* @__add(i8* %lft, i8* %rgt)
|
||||||
|
{
|
||||||
|
%lft_len = call i64 @__strlen(i8* %lft)
|
||||||
|
%rgt_len = call i64 @__strlen(i8* %rgt)
|
||||||
|
%new_len = add i64 %lft_len, %rgt_len
|
||||||
|
|
||||||
|
%res = call i8* @malloc(i64 %new_len)
|
||||||
|
; todo: copy lft
|
||||||
|
; todo: copy rgt
|
||||||
|
; todo: set 0 byte
|
||||||
|
ret i8* %res
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @__strlen(i8* %str)
|
||||||
|
{
|
||||||
|
start:
|
||||||
|
br label %loop_start
|
||||||
|
|
||||||
|
loop_start:
|
||||||
|
%i.0 = phi i64 [0, %start], [%i.new, %loop]
|
||||||
|
%c_adr = getelementptr i8, i8* %str, i64 %i.0
|
||||||
|
%c = load i8, i8* %c_adr
|
||||||
|
%done = icmp eq i8 %c, 0
|
||||||
|
br i1 %done, label %exit, label %loop
|
||||||
|
|
||||||
|
loop:
|
||||||
|
%i.new = add i64 %i.0, 1
|
||||||
|
br label %loop_start
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret i64 %i.0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8* @__mapgetkey(i8* %mapname, i8* %key, i8* %def)
|
||||||
|
{
|
||||||
|
; todo
|
||||||
|
ret i8* %def
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8* @addstringchar(i8* %0, i8* %1)
|
||||||
|
{
|
||||||
|
; todo
|
||||||
|
ret i8* %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8* @registerid(i8* %id_id)
|
||||||
|
{
|
||||||
|
%id_idname = call i8* @__mapgetkey(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str.01, i64 0, i64 0), i8* %id_id, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str.011, i64 0, i64 0))
|
||||||
|
%1 = call i64 @__strlen(i8* %id_idname)
|
||||||
|
%11 = icmp ne i64 %1, 0
|
||||||
|
br i1 %11, label %lbl1, label %lbl11
|
||||||
|
lbl1:
|
||||||
|
ret i8* %id_idname
|
||||||
|
lbl11:
|
||||||
|
%id_idnamea = call i8* @__add(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @str.0111, i64 0, i64 0), i8* %id_id)
|
||||||
|
ret i8* %id_idnamea
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64 @main() {
|
||||||
|
%res = call i64 @__strlen(i8* @str.01)
|
||||||
|
ret i64 %res
|
||||||
|
}
|
||||||
|
|
||||||
|
@str.01 = internal constant [11 x i8] c"REGISTERID\00"
|
||||||
|
@str.011 = internal constant [0 x i8] c""
|
||||||
|
@str.0111 = internal constant [3 x i8] c"id_"
|
||||||
19
3-lang0ll/foo.c
Normal file
19
3-lang0ll/foo.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void print(char * x)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum(int a, int b)
|
||||||
|
{
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char * foo = "Hello, world!";
|
||||||
|
printf("This is a test.");
|
||||||
|
|
||||||
|
return sum(7, 15);
|
||||||
|
}
|
||||||
889
3-lang0ll/lang0ll.lang0
Normal file
889
3-lang0ll/lang0ll.lang0
Normal file
@ -0,0 +1,889 @@
|
|||||||
|
registerid id:
|
||||||
|
declare idname
|
||||||
|
declare newidx
|
||||||
|
|
||||||
|
calc idname mapgetkey "REGISTERID" id ""
|
||||||
|
if idname
|
||||||
|
return idname
|
||||||
|
/
|
||||||
|
|
||||||
|
declare idnamea
|
||||||
|
calc idnamea add "%id_" id
|
||||||
|
return idnamea
|
||||||
|
/
|
||||||
|
|
||||||
|
emitln data:
|
||||||
|
emit data
|
||||||
|
emit eol
|
||||||
|
return ""
|
||||||
|
/
|
||||||
|
|
||||||
|
makelocalvar:
|
||||||
|
declare prevvar
|
||||||
|
declare newvar
|
||||||
|
declare result
|
||||||
|
calc prevvar mapgetkey "localvarused" "" ""
|
||||||
|
calc newvar add prevvar "1"
|
||||||
|
mapsetkey "localvarused" "" newvar
|
||||||
|
calc result add "%tmp" newvar
|
||||||
|
return result
|
||||||
|
/
|
||||||
|
|
||||||
|
makelocallabel:
|
||||||
|
declare prevlabel
|
||||||
|
declare newlabel
|
||||||
|
declare result
|
||||||
|
calc prevlabel mapgetkey "locallabelused" "" ""
|
||||||
|
calc newlabel add prevlabel "1"
|
||||||
|
mapsetkey "locallabelused" "" newlabel
|
||||||
|
calc result add "lbl" newlabel
|
||||||
|
return result
|
||||||
|
/
|
||||||
|
|
||||||
|
makestringconst str:
|
||||||
|
declare constid
|
||||||
|
declare isempty
|
||||||
|
|
||||||
|
calc constid mapgetkey "stringconst" str ""
|
||||||
|
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
|
||||||
|
|
||||||
|
return constid
|
||||||
|
/
|
||||||
|
|
||||||
|
lexident:
|
||||||
|
declare char
|
||||||
|
declare isbeforea
|
||||||
|
declare isafterz
|
||||||
|
declare word
|
||||||
|
set word ""
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isbeforea lt char "a"
|
||||||
|
if isbeforea
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc isafterz lt "z" char
|
||||||
|
if isafterz
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc word add word char
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
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
|
||||||
|
return ""
|
||||||
|
/
|
||||||
|
|
||||||
|
increaseindent indent:
|
||||||
|
calc indent add indent " "
|
||||||
|
return indent
|
||||||
|
/
|
||||||
|
|
||||||
|
parseconststring:
|
||||||
|
declare char
|
||||||
|
declare iseof
|
||||||
|
declare isquote
|
||||||
|
declare str
|
||||||
|
set str ""
|
||||||
|
skipchar quote
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseof eq char eof
|
||||||
|
if iseof
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc isquote eq char quote
|
||||||
|
if isquote
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc str add str char
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
skipchar quote
|
||||||
|
|
||||||
|
declare constid
|
||||||
|
calc constid makestringconst str
|
||||||
|
|
||||||
|
emit "i8* @str."
|
||||||
|
emit constid
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprvarref:
|
||||||
|
declare varid
|
||||||
|
declare varname
|
||||||
|
calc varname lexident
|
||||||
|
calc varid registerid varname
|
||||||
|
emit "i8* "
|
||||||
|
emit varid
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprcall:
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare funcid
|
||||||
|
declare funcname
|
||||||
|
declare isspace
|
||||||
|
declare isnotspace
|
||||||
|
declare isfirst
|
||||||
|
declare isnotfirst
|
||||||
|
declare isquote
|
||||||
|
declare isnotquote
|
||||||
|
calc funcname lexident
|
||||||
|
check mapgetkey "FUNCREG" funcname "" : "Function" funcname "does not exist"
|
||||||
|
emit "@id_"
|
||||||
|
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 ")"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatdeclare indent:
|
||||||
|
declare varid
|
||||||
|
declare varname
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
skipchar eol
|
||||||
|
|
||||||
|
calc varid registerid varname
|
||||||
|
emit indent
|
||||||
|
emit varid
|
||||||
|
emitln " = alloca i8*"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatset indent:
|
||||||
|
declare tmpvar
|
||||||
|
declare varid
|
||||||
|
declare varname
|
||||||
|
|
||||||
|
calc tmpvar makelocalvar
|
||||||
|
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
calc varid registerid varname
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit tmpvar
|
||||||
|
emit " = call i8* @__drop_i8_type("
|
||||||
|
parseconststring
|
||||||
|
emit ")"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "store i8* "
|
||||||
|
emit tmpvar
|
||||||
|
emit ", i8**"
|
||||||
|
emit varid
|
||||||
|
emitln ""
|
||||||
|
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatcalc indent:
|
||||||
|
declare varid
|
||||||
|
declare varname
|
||||||
|
declare tmpvar
|
||||||
|
|
||||||
|
calc tmpvar makelocalvar
|
||||||
|
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
calc varid registerid varname
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit tmpvar
|
||||||
|
emit " = call i8* "
|
||||||
|
parseexprcall
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "store i8* "
|
||||||
|
emit tmpvar
|
||||||
|
emit ", i8**"
|
||||||
|
emit varid
|
||||||
|
emitln ""
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseblock indent/
|
||||||
|
|
||||||
|
parsestatif indent:
|
||||||
|
declare labelempty
|
||||||
|
declare labelnotempty
|
||||||
|
declare strlenvar
|
||||||
|
declare strnotemptyvar
|
||||||
|
|
||||||
|
calc strlenvar makelocalvar
|
||||||
|
calc strnotemptyvar makelocalvar
|
||||||
|
|
||||||
|
calc labelempty makelocallabel
|
||||||
|
calc labelnotempty makelocallabel
|
||||||
|
|
||||||
|
skipchar " "
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit strlenvar
|
||||||
|
emit " = call i64 @__strlen("
|
||||||
|
parseexprvarref
|
||||||
|
skipchar eol
|
||||||
|
emitln ")"
|
||||||
|
emit indent
|
||||||
|
emit strnotemptyvar
|
||||||
|
emit " = icmp ne i64 "
|
||||||
|
emit strlenvar
|
||||||
|
emitln ", 0"
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "br i1 "
|
||||||
|
emit strnotemptyvar
|
||||||
|
emit ", label %"
|
||||||
|
emit labelnotempty
|
||||||
|
emit ", label %"
|
||||||
|
emitln labelempty
|
||||||
|
|
||||||
|
emit labelnotempty
|
||||||
|
emitln ":"
|
||||||
|
declare indentt
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
|
||||||
|
emit indentt
|
||||||
|
emit "br label %"
|
||||||
|
emitln labelempty
|
||||||
|
|
||||||
|
emit labelempty
|
||||||
|
emitln ":"
|
||||||
|
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatforever indent:
|
||||||
|
declare endlabel
|
||||||
|
declare indentt
|
||||||
|
declare startlabel
|
||||||
|
|
||||||
|
calc endlabel makelocallabel
|
||||||
|
calc startlabel makelocallabel
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
|
||||||
|
mapsetkey "foreverstatendlabel" "" endlabel
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "br label %"
|
||||||
|
emitln startlabel
|
||||||
|
emit startlabel
|
||||||
|
emitln ":"
|
||||||
|
skipchar eol
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "br label %"
|
||||||
|
emitln startlabel
|
||||||
|
emit endlabel
|
||||||
|
emitln ":"
|
||||||
|
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatbreak indent:
|
||||||
|
declare endlabel
|
||||||
|
calc endlabel mapgetkey "foreverstatendlabel" "" "?"
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "br label %"
|
||||||
|
emitln endlabel
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatreturn indent:
|
||||||
|
declare char
|
||||||
|
declare isspace
|
||||||
|
declare isnotquote
|
||||||
|
declare isquote
|
||||||
|
declare isnotspace
|
||||||
|
emit indent
|
||||||
|
emit "ret "
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isspace
|
||||||
|
skip
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
/
|
||||||
|
if isnotspace
|
||||||
|
emit "i8* @str.EMPTY"
|
||||||
|
/
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatcheck indent:
|
||||||
|
declare char
|
||||||
|
declare funcid
|
||||||
|
declare funcname
|
||||||
|
declare iscolon
|
||||||
|
declare iseol
|
||||||
|
declare isnotquote
|
||||||
|
declare isquote
|
||||||
|
declare notfirst
|
||||||
|
|
||||||
|
declare funcresvar
|
||||||
|
declare labelfail
|
||||||
|
declare labelnotfail
|
||||||
|
declare strlenvar
|
||||||
|
declare strnotemptyvar
|
||||||
|
declare stderrvar
|
||||||
|
|
||||||
|
calc funcresvar makelocalvar
|
||||||
|
calc strlenvar makelocalvar
|
||||||
|
calc strnotemptyvar makelocalvar
|
||||||
|
calc stderrvar makelocalvar
|
||||||
|
|
||||||
|
calc labelfail makelocallabel
|
||||||
|
calc labelnotfail makelocallabel
|
||||||
|
|
||||||
|
skipchar " "
|
||||||
|
|
||||||
|
calc funcname lexident
|
||||||
|
calc funcid registerid funcname
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit funcresvar
|
||||||
|
emit " = call i8* "
|
||||||
|
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
|
||||||
|
emit strlenvar
|
||||||
|
emit " = call i64 @__strlen(i8* "
|
||||||
|
emit funcresvar
|
||||||
|
emitln ")"
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit strnotemptyvar
|
||||||
|
emit " = icmp ne i64 "
|
||||||
|
emit strlenvar
|
||||||
|
emitln ", 0"
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "br i1 "
|
||||||
|
emit strnotemptyvar
|
||||||
|
emit ", label %"
|
||||||
|
emit labelnotfail
|
||||||
|
emit ", label %"
|
||||||
|
emitln labelfail
|
||||||
|
|
||||||
|
emit labelfail
|
||||||
|
emitln ":"
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit " "
|
||||||
|
emit stderrvar
|
||||||
|
emitln " = load %FILE*, %FILE** @stderrvar"
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit " call i32 @fputs(i8* @str.ERROR, %FILE* "
|
||||||
|
emit stderrvar
|
||||||
|
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 " call void @exit(i32 1)"
|
||||||
|
emit indent
|
||||||
|
emitln " unreachable"
|
||||||
|
|
||||||
|
emit labelnotfail
|
||||||
|
emitln ":"
|
||||||
|
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestattrace indent:
|
||||||
|
declare varid
|
||||||
|
declare varname
|
||||||
|
declare callconstid
|
||||||
|
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
skipchar eol
|
||||||
|
|
||||||
|
calc callconstid makestringconst varname
|
||||||
|
calc varid registerid varname
|
||||||
|
|
||||||
|
emit indent
|
||||||
|
emit "call void @__trace(i8* @str."
|
||||||
|
emit callconstid
|
||||||
|
emit ", i8* "
|
||||||
|
emit varid
|
||||||
|
emitln ")"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestat indent:
|
||||||
|
declare call
|
||||||
|
declare callid
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare iscall
|
||||||
|
declare isfirst
|
||||||
|
declare isspace
|
||||||
|
declare isquote
|
||||||
|
declare isnotfirst
|
||||||
|
declare isnotspace
|
||||||
|
declare isnotquote
|
||||||
|
calc call lexident
|
||||||
|
trace call
|
||||||
|
calc iscall eq call "declare"
|
||||||
|
if iscall
|
||||||
|
parsestatdeclare indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "set"
|
||||||
|
if iscall
|
||||||
|
parsestatset indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "calc"
|
||||||
|
if iscall
|
||||||
|
parsestatcalc indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "if"
|
||||||
|
if iscall
|
||||||
|
parsestatif indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "forever"
|
||||||
|
if iscall
|
||||||
|
parsestatforever indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "break"
|
||||||
|
if iscall
|
||||||
|
parsestatbreak indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "return"
|
||||||
|
if iscall
|
||||||
|
parsestatreturn indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "check"
|
||||||
|
if iscall
|
||||||
|
parsestatcheck indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
calc iscall eq call "trace"
|
||||||
|
if iscall
|
||||||
|
parsestattrace indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
check mapgetkey "FUNCREG" call "" : "Function" call "does not exist"
|
||||||
|
emit indent
|
||||||
|
emit "call i8* @id_"
|
||||||
|
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
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
skipchar eol
|
||||||
|
emitln ")"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseblock indent:
|
||||||
|
declare char
|
||||||
|
declare copy
|
||||||
|
declare iseol
|
||||||
|
declare isnoteol
|
||||||
|
declare isdone
|
||||||
|
declare iseoblock
|
||||||
|
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
|
||||||
|
/
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsefunc:
|
||||||
|
mapsetkey "localvarused" "" "0"
|
||||||
|
mapsetkey "locallabelused" "" "0"
|
||||||
|
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare funcid
|
||||||
|
declare funcname
|
||||||
|
declare iseoblock
|
||||||
|
declare isfirst
|
||||||
|
declare ismain
|
||||||
|
declare isnotmain
|
||||||
|
declare isspace
|
||||||
|
declare isnotfirst
|
||||||
|
declare isnotspace
|
||||||
|
declare varid
|
||||||
|
declare varname
|
||||||
|
calc funcname lexident
|
||||||
|
mapsetkey "FUNCREG" funcname "1"
|
||||||
|
trace funcname
|
||||||
|
emit "define i8* @id_"
|
||||||
|
emit funcname
|
||||||
|
emit "("
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc varname lexident
|
||||||
|
calc varid registerid varname
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
emit "i8* "
|
||||||
|
emit varid
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
skipchar "/"
|
||||||
|
skipchar eol
|
||||||
|
emitln " ; pre-declaration"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
skipchar ":"
|
||||||
|
skipchar eol
|
||||||
|
emitln ")"
|
||||||
|
emitln "{"
|
||||||
|
parseblock " "
|
||||||
|
emitln "}"
|
||||||
|
emit eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitheader:
|
||||||
|
emit "target datalayout = "
|
||||||
|
emit quote
|
||||||
|
emit "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
emit quote
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emit "target triple = "
|
||||||
|
emit quote
|
||||||
|
emit "x86_64-pc-linux-gnu"
|
||||||
|
emit quote
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emitln "%FILE = type opaque"
|
||||||
|
emitln "@stderr = external global %FILE*"
|
||||||
|
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emitln "declare void @exit(i32)"
|
||||||
|
emitln "declare i32 @fputs(i8*, %FILE*)"
|
||||||
|
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emit "@__EOL = internal constant [2 x i8] c"
|
||||||
|
emit quote
|
||||||
|
emit "\\0A\\00"
|
||||||
|
emitln quote
|
||||||
|
|
||||||
|
emit "@__QUOTE = internal constant [2 x i8] c"
|
||||||
|
emit quote
|
||||||
|
emit "\\22\\00"
|
||||||
|
emitln quote
|
||||||
|
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emitln "define i8* @__drop_i8_type(i8* %0) alwaysinline readnone"
|
||||||
|
emitln "{"
|
||||||
|
emitln " ret i8* %0"
|
||||||
|
emitln "}"
|
||||||
|
|
||||||
|
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitfooter:
|
||||||
|
declare constid
|
||||||
|
declare str
|
||||||
|
declare strlenvar
|
||||||
|
declare dontusethisstr
|
||||||
|
|
||||||
|
emit "@str.ERROR = internal constant [7 x i8] c"
|
||||||
|
emit quote
|
||||||
|
emit "ERROR:\\00"
|
||||||
|
emit quote
|
||||||
|
emitln ""
|
||||||
|
|
||||||
|
emit "@str.EMPTY = internal constant [1 x i8] c"
|
||||||
|
emit quote
|
||||||
|
emit "\\00"
|
||||||
|
emit quote
|
||||||
|
emitln ""
|
||||||
|
|
||||||
|
|
||||||
|
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 strlen
|
||||||
|
emit " x i8] c"
|
||||||
|
emit quote
|
||||||
|
emit str
|
||||||
|
emit "\\00"
|
||||||
|
emitln quote
|
||||||
|
|
||||||
|
calc constid add constid "1"
|
||||||
|
/
|
||||||
|
|
||||||
|
emit ""
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
main:
|
||||||
|
declare char
|
||||||
|
declare iseof
|
||||||
|
declare iseol
|
||||||
|
declare isnoteol
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
return
|
||||||
|
/
|
||||||
19
3-lang0ll/notes.ll
Normal file
19
3-lang0ll/notes.ll
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
define i8* @addstringchar(i8* %0, i8* %1)
|
||||||
|
{
|
||||||
|
; todo
|
||||||
|
ret i8* %0;
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8* @increaseindent(i8* %indent)
|
||||||
|
{
|
||||||
|
%indent.1 = call i8* @addstringchar(i8* %indent, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0));
|
||||||
|
%indent.2 = call i8* @addstringchar(i8* %indent.1, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0));
|
||||||
|
%indent.3 = call i8* @addstringchar(i8* %indent.2, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0));
|
||||||
|
%indent.4 = call i8* @addstringchar(i8* %indent.3, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0));
|
||||||
|
ret i8* %indent.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@.str = private unnamed_addr constant [14 x i8] c"Hello, world!\00", align 1
|
||||||
Loading…
x
Reference in New Issue
Block a user