Interpreter 1.0 Compiler 1.0 JIT 0.0
This commit is contained in:
commit
ac4f235592
14 changed files with 674 additions and 0 deletions
46
IR/IR.hs
Normal file
46
IR/IR.hs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{-# LANGUAGE TemplateHaskell #-}
|
||||
|
||||
module IR (setup, main_start, index_inc, index_dec, val_inc, val_dec, point, comma, paren_opening, paren_close, main_end) where
|
||||
|
||||
import Data.FileEmbed (embedStringFile)
|
||||
import Data.String (IsString)
|
||||
|
||||
setup :: (IsString a) => a
|
||||
setup = $(embedStringFile "IR/setup.ll")
|
||||
|
||||
main_start :: String
|
||||
main_start = "define void @main() {\n"
|
||||
|
||||
index_inc :: String
|
||||
index_inc = "call void @index_inc()\n"
|
||||
|
||||
index_dec :: String
|
||||
index_dec = "call void @index_dec()\n"
|
||||
|
||||
val_inc :: String
|
||||
val_inc = "call void @val_inc()\n"
|
||||
|
||||
val_dec :: String
|
||||
val_dec = "call void @val_dec()\n"
|
||||
|
||||
point :: String
|
||||
point = "call void @point()\n"
|
||||
|
||||
comma :: String
|
||||
comma = "call void @comma()\n"
|
||||
|
||||
paren :: String
|
||||
paren = "call i1 @paren()\n"
|
||||
|
||||
paren_opening :: (Num a, Show a) => a -> String
|
||||
paren_opening n = "br label %paren.start" ++ num ++ "\nparen.start" ++ num ++ ":\n%paren.cond" ++ num ++ " = " ++ paren ++ "\nbr i1 %paren.cond" ++ num ++ ", label %paren.body" ++ num ++ ", label %paren.end" ++ num ++ "\nparen.body" ++ num ++ ":\n"
|
||||
where
|
||||
num = show n
|
||||
|
||||
paren_close :: (Num a, Show a) => a -> String
|
||||
paren_close n = "br label %paren.start" ++ num ++ "\nparen.end" ++ num ++ ":\n"
|
||||
where
|
||||
num = show n
|
||||
|
||||
main_end :: String
|
||||
main_end = "ret void\n}\n"
|
||||
127
IR/setup.ll
Normal file
127
IR/setup.ll
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
define i64 @syscall(i64 %call, i64 %rdi, i64 %rsi, i64 %rdx, i64 %r10, i64 %r8, i64 %r9) alwaysinline {
|
||||
%rax = call i64 asm sideeffect inteldialect
|
||||
"syscall",
|
||||
"={rax},{rax},{rdi},{rsi},{rdx},{r10},{r8},{r9},~{rcx},~{r11},~{memory}"
|
||||
(i64 %call, i64 %rdi, i64 %rsi, i64 %rdx, i64 %r10, i64 %r8, i64 %r9)
|
||||
ret i64 %rax
|
||||
}
|
||||
|
||||
define void @exit(i64 %exitcode) alwaysinline noreturn {
|
||||
call i64 @syscall(i64 60, i64 %exitcode, i64 undef,i64 undef,i64 undef,i64 undef,i64 undef)
|
||||
call void asm sideeffect "hlt", ""() noreturn
|
||||
unreachable
|
||||
}
|
||||
|
||||
define i8 @read() alwaysinline{
|
||||
%buf = alloca i8
|
||||
%ret = call i64 @syscall(i64 0, i64 0, ptr %buf, i64 1, i64 undef,i64 undef,i64 undef)
|
||||
%ret.bool = trunc i64 %ret to i1
|
||||
br i1 %ret.bool, label %normal, label %error
|
||||
|
||||
error:
|
||||
call void @exit(i64 1)
|
||||
ret i8 0
|
||||
|
||||
normal:
|
||||
%char = load i8, ptr %buf
|
||||
ret i8 %char
|
||||
}
|
||||
|
||||
define i1 @write(i8 %char) alwaysinline {
|
||||
%buf = alloca i8
|
||||
store i8 %char, ptr %buf
|
||||
%nwrite = call i64 @syscall(i64 1, i64 1, ptr %buf, i64 1, i64 undef,i64 undef,i64 undef)
|
||||
%wrote = trunc i64 %nwrite to i1
|
||||
ret i1 %wrote
|
||||
}
|
||||
|
||||
define void @_start() naked {
|
||||
; clear %rbp
|
||||
call void asm sideeffect "", "{rbp}"(i64 0)
|
||||
|
||||
; read rsp
|
||||
%rsp = call ptr asm "", "={rsp},{rsp}"(ptr undef)
|
||||
|
||||
call void @main()
|
||||
|
||||
call void @exit(i64 0)
|
||||
ret void
|
||||
}
|
||||
|
||||
@arr = global [30000 x i16] zeroinitializer
|
||||
@index = global i16 0
|
||||
|
||||
define void @index_inc() alwaysinline {
|
||||
%i = load i16, ptr @index
|
||||
%i.i = add i16 %i, 1
|
||||
%i.final = urem i16 %i.i, 30000
|
||||
store i16 %i.final, ptr @index
|
||||
ret void
|
||||
}
|
||||
define void @index_dec() alwaysinline {
|
||||
%i = load i16, ptr @index
|
||||
%i.i = sub i16 %i, 1
|
||||
%i.final = urem i16 %i.i, 30000
|
||||
store i16 %i.final, ptr @index
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @val_inc() alwaysinline {
|
||||
%index = load i16, ptr @index
|
||||
%index.ext = sext i16 %index to i64
|
||||
|
||||
%val.ptr = getelementptr inbounds [30000 x i8], ptr @arr, i64 0, i64 %index.ext
|
||||
%val = load i8, ptr %val.ptr
|
||||
%val.final = add i8 %val, 1
|
||||
store i8 %val.final, ptr %val.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @val_dec() alwaysinline {
|
||||
%index = load i16, ptr @index
|
||||
%index.ext = sext i16 %index to i64
|
||||
|
||||
%val.ptr = getelementptr inbounds [30000 x i8], ptr @arr, i64 0, i64 %index.ext
|
||||
%val = load i8, ptr %val.ptr
|
||||
%val.final = sub i8 %val, 1
|
||||
store i8 %val.final, ptr %val.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @point() alwaysinline {
|
||||
%index = load i16, ptr @index
|
||||
%index.ext = sext i16 %index to i64
|
||||
|
||||
%char.ptr = getelementptr inbounds [30000 x i8], ptr @arr, i64 0, i64 %index.ext
|
||||
%char = load i8, ptr %char.ptr
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
%wrote = call i1 @write(i8 %char)
|
||||
%res = xor i1 %wrote, true
|
||||
br i1 %res, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @comma() alwaysinline {
|
||||
%char = call i8 @read()
|
||||
%index = load i16, ptr @index
|
||||
%index.ext = sext i16 %index to i64
|
||||
|
||||
%char.dest = getelementptr inbounds [30000 x i8], ptr @arr, i64 0, i64 %index.ext
|
||||
store i8 %char, ptr %char.dest
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @paren() alwaysinline {
|
||||
%index = load i16, ptr @index
|
||||
%index.ext = sext i16 %index to i64
|
||||
|
||||
%val.ptr = getelementptr inbounds [30000 x i8], ptr @arr, i64 0, i64 %index.ext
|
||||
%val = load i8, ptr %val.ptr
|
||||
|
||||
%eql = icmp ne i8 %val, 0
|
||||
ret i1 %eql
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue