Start on llvm IR target
# Conflicts: # 0-lang0py/lang0py.py # 1-lang0py/lang0py.lang0 # 2-lang0c/lang0c.lang0 # Makefile # README.md
This commit is contained in:
parent
a08084230e
commit
9ddd04dfa4
4
3-lang0ll/.gitignore
vendored
Normal file
4
3-lang0ll/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/lang0c*.c
|
||||||
|
/lang0c*.exe
|
||||||
|
/lang0c*.ll
|
||||||
|
/lang0c*.o
|
||||||
42
3-lang0ll/Makefile
Normal file
42
3-lang0ll/Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
.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 -c $<
|
||||||
|
|
||||||
|
lang0ll0.exe: lang0ll0.o
|
||||||
|
gcc -o $@ $<
|
||||||
|
|
||||||
|
lang0ll1.ll: lang0ll.lang0 lang0ll0.exe
|
||||||
|
cat $< | ./lang0ll0.exe > $@
|
||||||
|
# Cannot diff on the first iteration - platform change
|
||||||
|
|
||||||
|
lang0ll2.ll: lang0ll.lang0 lang0ll1.exe
|
||||||
|
cat $< | ./lang0ll1.exe > $@
|
||||||
|
-diff lang0ll1.ll lang0ll2.ll
|
||||||
|
|
||||||
|
lang0ll.ll: lang0ll.lang0 lang0ll2.exe
|
||||||
|
cat $< | ./lang0ll2.exe > $@
|
||||||
|
-diff lang0ll2.ll lang0ll.ll
|
||||||
|
|
||||||
|
foo.ll: foo.c
|
||||||
|
clang -S -emit-llvm $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f lang0ll*.py lang0ll*.ll lang0ll*.o lang0ll*.exe foo.ll foo.o foo.exe
|
||||||
17
3-lang0ll/foo.c
Normal file
17
3-lang0ll/foo.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
void print(char * x)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum(int a, int b)
|
||||||
|
{
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char * foo = "Hello, world!";
|
||||||
|
print("This is a test.");
|
||||||
|
|
||||||
|
return sum(7, 15);
|
||||||
|
}
|
||||||
BIN
3-lang0ll/foo.exe
Executable file
BIN
3-lang0ll/foo.exe
Executable file
Binary file not shown.
49
3-lang0ll/foo.ll
Normal file
49
3-lang0ll/foo.ll
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
; ModuleID = 'foo.c'
|
||||||
|
source_filename = "foo.c"
|
||||||
|
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"
|
||||||
|
|
||||||
|
@.str = private unnamed_addr constant [14 x i8] c"Hello, world!\00", align 1
|
||||||
|
@.str.1 = private unnamed_addr constant [16 x i8] c"This is a test.\00", align 1
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone uwtable
|
||||||
|
define dso_local void @print(i8* noundef %0) #0 {
|
||||||
|
%2 = alloca i8*, align 8
|
||||||
|
store i8* %0, i8** %2, align 8
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone uwtable
|
||||||
|
define dso_local i32 @sum(i32 noundef %0, i32 noundef %1) #0 {
|
||||||
|
%3 = alloca i32, align 4
|
||||||
|
%4 = alloca i32, align 4
|
||||||
|
store i32 %0, i32* %3, align 4
|
||||||
|
store i32 %1, i32* %4, align 4
|
||||||
|
%5 = load i32, i32* %3, align 4
|
||||||
|
%6 = load i32, i32* %4, align 4
|
||||||
|
%7 = add nsw i32 %5, %6
|
||||||
|
ret i32 %7
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone uwtable
|
||||||
|
define dso_local i32 @main() #0 {
|
||||||
|
%1 = alloca i32, align 4
|
||||||
|
%2 = alloca i8*, align 8
|
||||||
|
store i32 0, i32* %1, align 4
|
||||||
|
store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0), i8** %2, align 8
|
||||||
|
call void @print(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.1, i64 0, i64 0))
|
||||||
|
%3 = call i32 @sum(i32 noundef 7, i32 noundef 15)
|
||||||
|
ret i32 %3
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||||
|
!llvm.ident = !{!5}
|
||||||
|
|
||||||
|
!0 = !{i32 1, !"wchar_size", i32 4}
|
||||||
|
!1 = !{i32 7, !"PIC Level", i32 2}
|
||||||
|
!2 = !{i32 7, !"PIE Level", i32 2}
|
||||||
|
!3 = !{i32 7, !"uwtable", i32 1}
|
||||||
|
!4 = !{i32 7, !"frame-pointer", i32 2}
|
||||||
|
!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"}
|
||||||
472
3-lang0ll/lang0ll.lang0
Normal file
472
3-lang0ll/lang0ll.lang0
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
increaseindent indent:
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
calc indent addstringchar indent " "
|
||||||
|
return indent
|
||||||
|
/
|
||||||
|
|
||||||
|
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 addstringchar word char
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
return word
|
||||||
|
/
|
||||||
|
|
||||||
|
parseconststring:
|
||||||
|
declare char
|
||||||
|
declare iseof
|
||||||
|
declare isquote
|
||||||
|
skipchar quote
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseof eq char eof
|
||||||
|
if iseof
|
||||||
|
break
|
||||||
|
/
|
||||||
|
calc isquote eq char quote
|
||||||
|
if isquote
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
skipchar quote
|
||||||
|
emit "i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0)"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprvarref:
|
||||||
|
declare varname
|
||||||
|
calc varname lexident
|
||||||
|
emit "i8* %"
|
||||||
|
emit varname
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseexprcall:
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare funcname
|
||||||
|
declare isspace
|
||||||
|
declare isnotspace
|
||||||
|
declare isfirst
|
||||||
|
declare isnotfirst
|
||||||
|
declare isquote
|
||||||
|
declare isnotquote
|
||||||
|
calc funcname lexident
|
||||||
|
emit funcname
|
||||||
|
emit "("
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
emit ")"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatdeclare indent:
|
||||||
|
declare var
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
emit indent
|
||||||
|
emit "char * var_"
|
||||||
|
emit var
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatset indent:
|
||||||
|
declare var
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "var_"
|
||||||
|
emit var
|
||||||
|
emit " = "
|
||||||
|
parseconststring
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatcalc indent:
|
||||||
|
declare var
|
||||||
|
declare varidx
|
||||||
|
skipchar " "
|
||||||
|
calc var lexident
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "%"
|
||||||
|
emit var
|
||||||
|
calc varidx mapgetkey "funcvarused" var
|
||||||
|
calc varidx intinc varidx
|
||||||
|
mapsetkey "funcvarused" var varidx
|
||||||
|
emit "."
|
||||||
|
emit varidx
|
||||||
|
emit " = call i8* @"
|
||||||
|
parseexprcall
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parseblock indent/
|
||||||
|
|
||||||
|
parsestatif indent:
|
||||||
|
declare indentt
|
||||||
|
skipchar " "
|
||||||
|
emit indent
|
||||||
|
emit "if ( 0 < strlen("
|
||||||
|
parseexprvarref
|
||||||
|
emit ") )\n"
|
||||||
|
emit indent
|
||||||
|
emit "{\n"
|
||||||
|
skipchar eol
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "}\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatforever indent:
|
||||||
|
declare indentt
|
||||||
|
emit indent
|
||||||
|
emit "while (1)\n"
|
||||||
|
emit indent
|
||||||
|
emit "{\n"
|
||||||
|
skipchar eol
|
||||||
|
calc indentt increaseindent indent
|
||||||
|
parseblock indentt
|
||||||
|
emit indent
|
||||||
|
emit "}\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatbreak indent:
|
||||||
|
emit indent
|
||||||
|
emit "break;\n"
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestatreturn indent:
|
||||||
|
declare char
|
||||||
|
declare isspace
|
||||||
|
declare isnotspace
|
||||||
|
emit indent
|
||||||
|
emit "ret "
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isspace
|
||||||
|
skip
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
if isnotspace
|
||||||
|
emit "i18* 0"
|
||||||
|
/
|
||||||
|
emit ";"
|
||||||
|
emit eol
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestattrace indent:
|
||||||
|
declare varname
|
||||||
|
emit indent
|
||||||
|
emit "trace("
|
||||||
|
emit quote
|
||||||
|
skipchar " "
|
||||||
|
calc varname lexident
|
||||||
|
emit varname
|
||||||
|
emit quote
|
||||||
|
emit ", var_"
|
||||||
|
emit varname
|
||||||
|
emit ");\n"
|
||||||
|
skipchar eol
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
parsestat indent:
|
||||||
|
declare call
|
||||||
|
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 "trace"
|
||||||
|
if iscall
|
||||||
|
parsestattrace indent
|
||||||
|
return
|
||||||
|
/
|
||||||
|
emit indent
|
||||||
|
emit call
|
||||||
|
emit "("
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc char peek
|
||||||
|
calc isquote eq char quote
|
||||||
|
calc isnotquote not isquote
|
||||||
|
if isquote
|
||||||
|
parseconststring
|
||||||
|
/
|
||||||
|
if isnotquote
|
||||||
|
parseexprvarref
|
||||||
|
/
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
skipchar eol
|
||||||
|
emit ");\n"
|
||||||
|
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:
|
||||||
|
declare char
|
||||||
|
declare first
|
||||||
|
declare funcname
|
||||||
|
declare iseoblock
|
||||||
|
declare isfirst
|
||||||
|
declare isspace
|
||||||
|
declare isnotfirst
|
||||||
|
declare isnotspace
|
||||||
|
declare var
|
||||||
|
mapclear "funcvarused"
|
||||||
|
calc funcname lexident
|
||||||
|
trace funcname
|
||||||
|
emit "define i8* @"
|
||||||
|
emit funcname
|
||||||
|
emit "("
|
||||||
|
set first "1"
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc isspace eq char " "
|
||||||
|
calc isnotspace not isspace
|
||||||
|
if isnotspace
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
calc var lexident
|
||||||
|
calc isfirst eq first "1"
|
||||||
|
calc isnotfirst not isfirst
|
||||||
|
if isnotfirst
|
||||||
|
emit ", "
|
||||||
|
/
|
||||||
|
emit "i8* %"
|
||||||
|
emit var
|
||||||
|
mapsetkey "funcvarused" "var" "0"
|
||||||
|
emit "_0"
|
||||||
|
set first "0"
|
||||||
|
/
|
||||||
|
calc char peek
|
||||||
|
calc iseoblock eq char "/"
|
||||||
|
if iseoblock
|
||||||
|
skipchar "/"
|
||||||
|
skipchar eol
|
||||||
|
emit ");"
|
||||||
|
emit "\n"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
skipchar ":"
|
||||||
|
skipchar eol
|
||||||
|
emit ")\n{\n"
|
||||||
|
parseblock " "
|
||||||
|
emit "}\n\n"
|
||||||
|
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
|
||||||
|
|
||||||
|
emit "define i8* @addstringchar(i8* %0, i8* %1)"
|
||||||
|
emit eol
|
||||||
|
emit "{"
|
||||||
|
emit eol
|
||||||
|
emit " ; todo"
|
||||||
|
emit eol
|
||||||
|
emit " ret i8* %0;"
|
||||||
|
emit eol
|
||||||
|
emit "}"
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
emit eol
|
||||||
|
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
emitfooter:
|
||||||
|
emit ""
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
main:
|
||||||
|
declare char
|
||||||
|
declare iseof
|
||||||
|
declare iseol
|
||||||
|
declare isnoteol
|
||||||
|
emitheader
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseof eq char eof
|
||||||
|
if iseof
|
||||||
|
break
|
||||||
|
/
|
||||||
|
forever
|
||||||
|
calc char peek
|
||||||
|
calc iseol eq char eol
|
||||||
|
calc isnoteol not iseol
|
||||||
|
if isnoteol
|
||||||
|
break
|
||||||
|
/
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
parsefunc
|
||||||
|
/
|
||||||
|
emitfooter
|
||||||
|
return
|
||||||
|
/
|
||||||
608
3-lang0ll/lang0ll0.c
Normal file
608
3-lang0ll/lang0ll0.c
Normal file
@ -0,0 +1,608 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
char var_eof[2] = {-1, 0};
|
||||||
|
char var_eol[2] = {10, 0};
|
||||||
|
char var_quote[2] = {34, 0};
|
||||||
|
char var_false[1] = {0};
|
||||||
|
char var_true[2] = {'1', 0};
|
||||||
|
|
||||||
|
|
||||||
|
char * eq(char * a, char * b)
|
||||||
|
{
|
||||||
|
return (strcmp(a, b) == 0) ? var_true : var_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * lt(char * a, char * b)
|
||||||
|
{
|
||||||
|
return (strcmp(a, b) < 0) ? var_true : var_false;
|
||||||
|
}
|
||||||
|
char * not(char * a)
|
||||||
|
{
|
||||||
|
return (strcmp(a, var_true) != 0) ? var_true : var_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * addstringchar(char * str, char * chr)
|
||||||
|
{
|
||||||
|
int str_len = strlen(str);
|
||||||
|
assert(strlen(chr) == 1);
|
||||||
|
char * res = malloc((str_len + 2) * sizeof(char));
|
||||||
|
strcpy(res, str);
|
||||||
|
res[str_len + 0] = chr[0];
|
||||||
|
res[str_len + 1] = 0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * emit(char * str)
|
||||||
|
{
|
||||||
|
fputs(str, stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * trace(char * var_name, char * var_value)
|
||||||
|
{
|
||||||
|
const char * env_trace = getenv("TRACE");
|
||||||
|
if( !env_trace ) return 0;
|
||||||
|
fputs(var_name, stderr);
|
||||||
|
fputs("=", stderr);
|
||||||
|
fputs(var_value, stderr);
|
||||||
|
fputs(var_eol, stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LINE = 1;
|
||||||
|
|
||||||
|
char * peek()
|
||||||
|
{
|
||||||
|
char * res = malloc(2*sizeof(char));
|
||||||
|
res[0] = getc(stdin);
|
||||||
|
res[1] = 0;
|
||||||
|
ungetc(res[0], stdin);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void skip()
|
||||||
|
{
|
||||||
|
char c = getc(stdin);
|
||||||
|
if( c == 10 ) LINE += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void skipchar(char * chr)
|
||||||
|
{
|
||||||
|
assert(strlen(chr) == 1);
|
||||||
|
char * act = peek();
|
||||||
|
assert(strlen(act) == 1);
|
||||||
|
if( chr[0] == act[0] ) {skip(); return;};
|
||||||
|
fprintf(stderr, "Expected '%c' on line %d but saw '%c' instead%c", chr[0], LINE, act[0], 10);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * increaseindent(char * var_indent)
|
||||||
|
{
|
||||||
|
var_indent = addstringchar(var_indent, " ");
|
||||||
|
var_indent = addstringchar(var_indent, " ");
|
||||||
|
var_indent = addstringchar(var_indent, " ");
|
||||||
|
var_indent = addstringchar(var_indent, " ");
|
||||||
|
return var_indent;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * lexident()
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_isbeforea;
|
||||||
|
char * var_isafterz;
|
||||||
|
char * var_word;
|
||||||
|
var_word = "";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_isbeforea = lt(var_char, "a");
|
||||||
|
if ( 0 < strlen(var_isbeforea) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var_isafterz = lt("z", var_char);
|
||||||
|
if ( 0 < strlen(var_isafterz) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var_word = addstringchar(var_word, var_char);
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
return var_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parseconststring()
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_iseof;
|
||||||
|
char * var_isquote;
|
||||||
|
skipchar(var_quote);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_iseof = eq(var_char, var_eof);
|
||||||
|
if ( 0 < strlen(var_iseof) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var_isquote = eq(var_char, var_quote);
|
||||||
|
if ( 0 < strlen(var_isquote) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
skipchar(var_quote);
|
||||||
|
emit("i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parseexprvarref()
|
||||||
|
{
|
||||||
|
char * var_varname;
|
||||||
|
var_varname = lexident();
|
||||||
|
emit("i8* %");
|
||||||
|
emit(var_varname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parseexprcall()
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_first;
|
||||||
|
char * var_funcname;
|
||||||
|
char * var_isspace;
|
||||||
|
char * var_isnotspace;
|
||||||
|
char * var_isfirst;
|
||||||
|
char * var_isnotfirst;
|
||||||
|
char * var_isquote;
|
||||||
|
char * var_isnotquote;
|
||||||
|
var_funcname = lexident();
|
||||||
|
emit(var_funcname);
|
||||||
|
emit("(");
|
||||||
|
var_first = "1";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_isspace = eq(var_char, " ");
|
||||||
|
var_isnotspace = not(var_isspace);
|
||||||
|
if ( 0 < strlen(var_isnotspace) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
var_isfirst = eq(var_first, "1");
|
||||||
|
var_isnotfirst = not(var_isfirst);
|
||||||
|
if ( 0 < strlen(var_isnotfirst) )
|
||||||
|
{
|
||||||
|
emit(", ");
|
||||||
|
}
|
||||||
|
var_char = peek();
|
||||||
|
var_isquote = eq(var_char, var_quote);
|
||||||
|
var_isnotquote = not(var_isquote);
|
||||||
|
if ( 0 < strlen(var_isquote) )
|
||||||
|
{
|
||||||
|
parseconststring();
|
||||||
|
}
|
||||||
|
if ( 0 < strlen(var_isnotquote) )
|
||||||
|
{
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
var_first = "0";
|
||||||
|
}
|
||||||
|
emit(")");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestatdeclare(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_var;
|
||||||
|
skipchar(" ");
|
||||||
|
var_var = lexident();
|
||||||
|
emit(var_indent);
|
||||||
|
emit("char * var_");
|
||||||
|
emit(var_var);
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestatset(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_var;
|
||||||
|
skipchar(" ");
|
||||||
|
var_var = lexident();
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("var_");
|
||||||
|
emit(var_var);
|
||||||
|
emit(" = ");
|
||||||
|
parseconststring();
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestatcalc(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_var;
|
||||||
|
char * var_varidx;
|
||||||
|
skipchar(" ");
|
||||||
|
var_var = lexident();
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("%");
|
||||||
|
emit(var_var);
|
||||||
|
var_varidx = mapgetkey("funcvarused", var_var);
|
||||||
|
var_varidx = intinc(var_varidx);
|
||||||
|
mapsetkey("funcvarused"var_var, var_varidx, );
|
||||||
|
emit(".");
|
||||||
|
emit(var_varidx);
|
||||||
|
emit(" = call i8* @");
|
||||||
|
parseexprcall();
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parseblock(char * var_indent);
|
||||||
|
char * parsestatif(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_indentt;
|
||||||
|
skipchar(" ");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("if ( 0 < strlen(");
|
||||||
|
parseexprvarref();
|
||||||
|
emit(") )\n");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("{\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
var_indentt = increaseindent(var_indent);
|
||||||
|
parseblock(var_indentt);
|
||||||
|
emit(var_indent);
|
||||||
|
emit("}\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestatforever(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_indentt;
|
||||||
|
emit(var_indent);
|
||||||
|
emit("while (1)\n");
|
||||||
|
emit(var_indent);
|
||||||
|
emit("{\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
var_indentt = increaseindent(var_indent);
|
||||||
|
parseblock(var_indentt);
|
||||||
|
emit(var_indent);
|
||||||
|
emit("}\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestatbreak(char * var_indent)
|
||||||
|
{
|
||||||
|
emit(var_indent);
|
||||||
|
emit("break;\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestatreturn(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_isspace;
|
||||||
|
char * var_isnotspace;
|
||||||
|
emit(var_indent);
|
||||||
|
emit("ret ");
|
||||||
|
var_char = peek();
|
||||||
|
var_isspace = eq(var_char, " ");
|
||||||
|
var_isnotspace = not(var_isspace);
|
||||||
|
if ( 0 < strlen(var_isspace) )
|
||||||
|
{
|
||||||
|
skip();
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
if ( 0 < strlen(var_isnotspace) )
|
||||||
|
{
|
||||||
|
emit("i18* 0");
|
||||||
|
}
|
||||||
|
emit(";");
|
||||||
|
emit(var_eol);
|
||||||
|
skipchar(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestattrace(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_varname;
|
||||||
|
emit(var_indent);
|
||||||
|
emit("trace(");
|
||||||
|
emit(var_quote);
|
||||||
|
skipchar(" ");
|
||||||
|
var_varname = lexident();
|
||||||
|
emit(var_varname);
|
||||||
|
emit(var_quote);
|
||||||
|
emit(", var_");
|
||||||
|
emit(var_varname);
|
||||||
|
emit(");\n");
|
||||||
|
skipchar(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsestat(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_call;
|
||||||
|
char * var_char;
|
||||||
|
char * var_first;
|
||||||
|
char * var_iscall;
|
||||||
|
char * var_isfirst;
|
||||||
|
char * var_isspace;
|
||||||
|
char * var_isquote;
|
||||||
|
char * var_isnotfirst;
|
||||||
|
char * var_isnotspace;
|
||||||
|
char * var_isnotquote;
|
||||||
|
var_call = lexident();
|
||||||
|
trace("call", var_call);
|
||||||
|
var_iscall = eq(var_call, "declare");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatdeclare(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "set");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatset(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "calc");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatcalc(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "if");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatif(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "forever");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatforever(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "break");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatbreak(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "return");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestatreturn(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var_iscall = eq(var_call, "trace");
|
||||||
|
if ( 0 < strlen(var_iscall) )
|
||||||
|
{
|
||||||
|
parsestattrace(var_indent);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
emit(var_indent);
|
||||||
|
emit(var_call);
|
||||||
|
emit("(");
|
||||||
|
var_first = "1";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_isspace = eq(var_char, " ");
|
||||||
|
var_isnotspace = not(var_isspace);
|
||||||
|
if ( 0 < strlen(var_isnotspace) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
var_char = peek();
|
||||||
|
var_isquote = eq(var_char, var_quote);
|
||||||
|
var_isnotquote = not(var_isquote);
|
||||||
|
if ( 0 < strlen(var_isquote) )
|
||||||
|
{
|
||||||
|
parseconststring();
|
||||||
|
}
|
||||||
|
if ( 0 < strlen(var_isnotquote) )
|
||||||
|
{
|
||||||
|
parseexprvarref();
|
||||||
|
}
|
||||||
|
var_isfirst = eq(var_first, "1");
|
||||||
|
var_isnotfirst = not(var_isfirst);
|
||||||
|
if ( 0 < strlen(var_isnotfirst) )
|
||||||
|
{
|
||||||
|
emit(", ");
|
||||||
|
}
|
||||||
|
var_first = "0";
|
||||||
|
}
|
||||||
|
skipchar(var_eol);
|
||||||
|
emit(");\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parseblock(char * var_indent)
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_copy;
|
||||||
|
char * var_iseol;
|
||||||
|
char * var_isnoteol;
|
||||||
|
char * var_isdone;
|
||||||
|
char * var_iseoblock;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_iseol = eq(var_char, var_eol);
|
||||||
|
var_isnoteol = not(var_iseol);
|
||||||
|
if ( 0 < strlen(var_isnoteol) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
var_copy = " ";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_isdone = eq(var_copy, var_indent);
|
||||||
|
if ( 0 < strlen(var_isdone) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skipchar("\t");
|
||||||
|
var_copy = increaseindent(var_copy);
|
||||||
|
}
|
||||||
|
var_char = peek();
|
||||||
|
var_iseoblock = eq(var_char, "/");
|
||||||
|
if ( 0 < strlen(var_iseoblock) )
|
||||||
|
{
|
||||||
|
skip();
|
||||||
|
skipchar(var_eol);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skipchar("\t");
|
||||||
|
parsestat(var_indent);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * parsefunc()
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_first;
|
||||||
|
char * var_funcname;
|
||||||
|
char * var_iseoblock;
|
||||||
|
char * var_isfirst;
|
||||||
|
char * var_isspace;
|
||||||
|
char * var_isnotfirst;
|
||||||
|
char * var_isnotspace;
|
||||||
|
char * var_var;
|
||||||
|
mapclear("funcvarused");
|
||||||
|
var_funcname = lexident();
|
||||||
|
trace("funcname", var_funcname);
|
||||||
|
emit("define i8* @");
|
||||||
|
emit(var_funcname);
|
||||||
|
emit("(");
|
||||||
|
var_first = "1";
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_isspace = eq(var_char, " ");
|
||||||
|
var_isnotspace = not(var_isspace);
|
||||||
|
if ( 0 < strlen(var_isnotspace) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
var_var = lexident();
|
||||||
|
var_isfirst = eq(var_first, "1");
|
||||||
|
var_isnotfirst = not(var_isfirst);
|
||||||
|
if ( 0 < strlen(var_isnotfirst) )
|
||||||
|
{
|
||||||
|
emit(", ");
|
||||||
|
}
|
||||||
|
emit("i8* %");
|
||||||
|
emit(var_var);
|
||||||
|
mapsetkey("funcvarused""var", "0", );
|
||||||
|
emit("_0");
|
||||||
|
var_first = "0";
|
||||||
|
}
|
||||||
|
var_char = peek();
|
||||||
|
var_iseoblock = eq(var_char, "/");
|
||||||
|
if ( 0 < strlen(var_iseoblock) )
|
||||||
|
{
|
||||||
|
skipchar("/");
|
||||||
|
skipchar(var_eol);
|
||||||
|
emit(");");
|
||||||
|
emit("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
skipchar(":");
|
||||||
|
skipchar(var_eol);
|
||||||
|
emit(")\n{\n");
|
||||||
|
parseblock(" ");
|
||||||
|
emit("}\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * emitheader()
|
||||||
|
{
|
||||||
|
emit("target datalayout = ");
|
||||||
|
emit(var_quote);
|
||||||
|
emit("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128");
|
||||||
|
emit(var_quote);
|
||||||
|
emit(var_eol);
|
||||||
|
emit("target triple = ");
|
||||||
|
emit(var_quote);
|
||||||
|
emit("x86_64-pc-linux-gnu");
|
||||||
|
emit(var_quote);
|
||||||
|
emit(var_eol);
|
||||||
|
emit(var_eol);
|
||||||
|
emit("define i8* @addstringchar(i8* %0, i8* %1)");
|
||||||
|
emit(var_eol);
|
||||||
|
emit("{");
|
||||||
|
emit(var_eol);
|
||||||
|
emit(" ; todo");
|
||||||
|
emit(var_eol);
|
||||||
|
emit(" ret i8* %0;");
|
||||||
|
emit(var_eol);
|
||||||
|
emit("}");
|
||||||
|
emit(var_eol);
|
||||||
|
emit(var_eol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * emitfooter()
|
||||||
|
{
|
||||||
|
emit("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * main()
|
||||||
|
{
|
||||||
|
char * var_char;
|
||||||
|
char * var_iseof;
|
||||||
|
char * var_iseol;
|
||||||
|
char * var_isnoteol;
|
||||||
|
emitheader();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_iseof = eq(var_char, var_eof);
|
||||||
|
if ( 0 < strlen(var_iseof) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
var_char = peek();
|
||||||
|
var_iseol = eq(var_char, var_eol);
|
||||||
|
var_isnoteol = not(var_iseol);
|
||||||
|
if ( 0 < strlen(var_isnoteol) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
parsefunc();
|
||||||
|
}
|
||||||
|
emitfooter();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
32
README.md
32
README.md
@ -133,12 +133,44 @@ Writes the given string to standard output.
|
|||||||
|
|
||||||
Return true if the given strings are the same.
|
Return true if the given strings are the same.
|
||||||
|
|
||||||
|
#### intinc a
|
||||||
|
|
||||||
|
Available in it2 runtime and onwards.
|
||||||
|
|
||||||
|
Interprets string `a` as an integer, increases it by one and returns it (as a string).
|
||||||
|
If `a` cannot be interpreted as an integer, or has additional bytes, this function returns 1.
|
||||||
|
|
||||||
#### lt a b
|
#### lt a b
|
||||||
|
|
||||||
`a` and `b` are expected to have length 1.
|
`a` and `b` are expected to have length 1.
|
||||||
|
|
||||||
Return true if a would sort before b.
|
Return true if a would sort before b.
|
||||||
|
|
||||||
|
#### mapclear mapname
|
||||||
|
|
||||||
|
Available in it2 runtime and onwards.
|
||||||
|
|
||||||
|
Maps are global and can be used from any function.
|
||||||
|
|
||||||
|
Clears all values set in the map named `mapname`.
|
||||||
|
|
||||||
|
#### mapgetkey mapname key
|
||||||
|
|
||||||
|
Available in it2 runtime and onwards.
|
||||||
|
|
||||||
|
Maps are global and can be used from any function.
|
||||||
|
|
||||||
|
Looks up `key` in the map named `mapname` and returns it.
|
||||||
|
If not found, returns an empty string.
|
||||||
|
|
||||||
|
#### mapsetkey mapname key value
|
||||||
|
|
||||||
|
Available in it2 runtime and onwards.
|
||||||
|
|
||||||
|
Maps are global and can be used from any function.
|
||||||
|
|
||||||
|
Adds a mapping from `key` to `value` to the map named `mapname`.
|
||||||
|
|
||||||
#### peek
|
#### peek
|
||||||
|
|
||||||
Checks stdin for the next character and returns it.
|
Checks stdin for the next character and returns it.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user