Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
82df5ecc
wa
项目概览
wa-lang
/
wa
大约 1 年 前同步成功
通知
68
Star
655
Fork
45
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
wa
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
82df5ecc
编写于
10月 27, 2022
作者:
B
Ben Shi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement translation of unary and binary operations.
上级
25e94ac9
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
177 addition
and
11 deletion
+177
-11
hello.wa
hello.wa
+7
-3
internal/backends/compiler_llvm/compile_function.go
internal/backends/compiler_llvm/compile_function.go
+6
-5
internal/backends/compiler_llvm/compile_value.go
internal/backends/compiler_llvm/compile_value.go
+117
-0
internal/backends/compiler_llvm/utils.go
internal/backends/compiler_llvm/utils.go
+47
-3
未找到文件。
hello.wa
浏览文件 @
82df5ecc
...
@@ -6,9 +6,13 @@ fn main {
...
@@ -6,9 +6,13 @@ fn main {
print('言')
print('言')
print('\n')
print('\n')
println(
add(40, 2
))
println(
calc0(42, 5, 3
))
}
}
fn add(a: i32, b: i32) => i32 {
fn calc0(a: i32, b: i32, c: i32) => i32 {
return a + b
return a * 5 / (b - c + 1)
}
fn calc2(a: float32, b: float32, c: float32) => float32 {
return a * 5 / (b - c + 1)
}
}
internal/backends/compiler_llvm/compile_function.go
浏览文件 @
82df5ecc
...
@@ -54,18 +54,19 @@ func (p *Compiler) compileInstr(instr ssa.Instruction) error {
...
@@ -54,18 +54,19 @@ func (p *Compiler) compileInstr(instr ssa.Instruction) error {
case
0
:
case
0
:
p
.
output
.
WriteString
(
" ret void
\n
"
)
p
.
output
.
WriteString
(
" ret void
\n
"
)
case
1
:
// ret %type %value
case
1
:
// ret %type %value
p
.
output
.
WriteString
(
"
;
ret "
)
p
.
output
.
WriteString
(
" ret "
)
p
.
output
.
WriteString
(
getTypeStr
(
instr
.
Results
[
0
]
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
getTypeStr
(
instr
.
Results
[
0
]
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
" %"
+
instr
.
Results
[
0
]
.
Name
())
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
"
\n
"
)
p
.
output
.
WriteString
(
getValueStr
(
instr
.
Results
[
0
]))
p
.
output
.
WriteString
(
" ret "
+
getTypeStr
(
instr
.
Results
[
0
]
.
Type
(),
p
.
target
)
+
" 1"
)
p
.
output
.
WriteString
(
"
\n
"
)
p
.
output
.
WriteString
(
"
\n
"
)
default
:
default
:
return
errors
.
New
(
"multiple return values are not supported"
)
return
errors
.
New
(
"multiple return values are not supported"
)
}
}
case
ssa
.
Value
:
case
ssa
.
Value
:
p
.
output
.
WriteString
(
" ; "
+
instr
.
Name
()
+
" = "
+
instr
.
String
()
+
"
\n
"
)
if
err
:=
p
.
compileValue
(
instr
);
err
!=
nil
{
return
err
}
default
:
default
:
p
.
output
.
WriteString
(
" ; "
+
instr
.
String
()
+
"
\n
"
)
p
.
output
.
WriteString
(
" ; "
+
instr
.
String
()
+
"
\n
"
)
...
...
internal/backends/compiler_llvm/compile_value.go
0 → 100644
浏览文件 @
82df5ecc
// 版权 @2022 凹语言 作者。保留所有权利。
package
compiler_llvm
import
(
"github.com/wa-lang/wa/internal/ssa"
"github.com/wa-lang/wa/internal/token"
)
func
(
p
*
Compiler
)
compileValue
(
val
ssa
.
Value
)
error
{
switch
val
:=
val
.
(
type
)
{
case
*
ssa
.
UnOp
:
if
err
:=
p
.
compileUnOp
(
val
);
err
!=
nil
{
return
err
}
case
*
ssa
.
BinOp
:
if
err
:=
p
.
compileBinOp
(
val
);
err
!=
nil
{
return
err
}
case
*
ssa
.
Call
:
if
err
:=
p
.
compileCall
(
val
);
err
!=
nil
{
return
err
}
default
:
p
.
output
.
WriteString
(
" ; "
+
val
.
Name
()
+
" = "
+
val
.
String
()
+
"
\n
"
)
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
}
return
nil
}
func
(
p
*
Compiler
)
compileUnOp
(
val
*
ssa
.
UnOp
)
error
{
switch
val
.
Op
{
case
token
.
SUB
:
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
"%"
+
val
.
Name
())
p
.
output
.
WriteString
(
" = "
)
if
isFloat
,
_
:=
checkType
(
val
.
X
.
Type
());
isFloat
{
p
.
output
.
WriteString
(
"fneg "
)
p
.
output
.
WriteString
(
getTypeStr
(
val
.
X
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
" "
)
}
else
{
p
.
output
.
WriteString
(
"sub "
)
p
.
output
.
WriteString
(
getTypeStr
(
val
.
X
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
" 0, "
)
}
p
.
output
.
WriteString
(
getValueStr
(
val
.
X
))
p
.
output
.
WriteString
(
"
\n
"
)
default
:
p
.
output
.
WriteString
(
" ; "
+
val
.
Name
()
+
" = "
+
val
.
String
()
+
"
\n
"
)
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
}
return
nil
}
func
(
p
*
Compiler
)
compileBinOp
(
val
*
ssa
.
BinOp
)
error
{
sintOpMap
:=
map
[
token
.
Token
]
string
{
token
.
ADD
:
"add"
,
token
.
SUB
:
"sub"
,
token
.
MUL
:
"mul"
,
token
.
QUO
:
"sdiv"
,
token
.
REM
:
"srem"
,
}
uintOpMap
:=
map
[
token
.
Token
]
string
{
token
.
ADD
:
"add"
,
token
.
SUB
:
"sub"
,
token
.
MUL
:
"mul"
,
token
.
QUO
:
"udiv"
,
token
.
REM
:
"urem"
,
}
floatOpMap
:=
map
[
token
.
Token
]
string
{
token
.
ADD
:
"fadd"
,
token
.
SUB
:
"fsub"
,
token
.
MUL
:
"fmul"
,
token
.
QUO
:
"fdiv"
,
}
// Type float, signed int, unsigned int each has its own LLVM-IR.
var
opMap
map
[
token
.
Token
]
string
isFloat
,
isSigned
:=
checkType
(
val
.
X
.
Type
())
if
isFloat
{
opMap
=
floatOpMap
}
else
if
isSigned
{
opMap
=
sintOpMap
}
else
{
opMap
=
uintOpMap
}
if
op
,
ok
:=
opMap
[
val
.
Op
];
ok
{
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
"%"
+
val
.
Name
())
p
.
output
.
WriteString
(
" = "
)
p
.
output
.
WriteString
(
op
)
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
getTypeStr
(
val
.
X
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
getValueStr
(
val
.
X
))
p
.
output
.
WriteString
(
", "
)
p
.
output
.
WriteString
(
getValueStr
(
val
.
Y
))
p
.
output
.
WriteString
(
"
\n
"
)
return
nil
}
p
.
output
.
WriteString
(
" ; "
+
val
.
Name
()
+
" = "
+
val
.
String
()
+
"
\n
"
)
return
nil
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
}
func
(
p
*
Compiler
)
compileCall
(
val
*
ssa
.
Call
)
error
{
p
.
output
.
WriteString
(
" ; "
+
val
.
Name
()
+
" = "
+
val
.
String
()
+
"
\n
"
)
return
nil
}
internal/backends/compiler_llvm/utils.go
浏览文件 @
82df5ecc
...
@@ -3,8 +3,11 @@
...
@@ -3,8 +3,11 @@
package
compiler_llvm
package
compiler_llvm
import
(
import
(
"fmt"
"strconv"
"strings"
"strings"
"github.com/wa-lang/wa/internal/ssa"
"github.com/wa-lang/wa/internal/types"
"github.com/wa-lang/wa/internal/types"
)
)
...
@@ -16,6 +19,26 @@ func getArch(arch string) string {
...
@@ -16,6 +19,26 @@ func getArch(arch string) string {
return
arch
[
0
:
pos
]
return
arch
[
0
:
pos
]
}
}
func
checkType
(
from
types
.
Type
)
(
isFloat
bool
,
isSigned
bool
)
{
switch
t
:=
from
.
(
type
)
{
case
*
types
.
Basic
:
switch
t
.
Kind
()
{
case
types
.
Float32
,
types
.
Float64
,
types
.
UntypedFloat
:
return
true
,
true
case
types
.
Uint8
,
types
.
Uint16
,
types
.
Uint32
,
types
.
Uint64
,
types
.
Uint
:
return
false
,
false
case
types
.
Bool
,
types
.
UntypedBool
,
types
.
Int8
,
types
.
Int16
,
types
.
Int32
,
types
.
Int64
,
types
.
Int
,
types
.
UntypedInt
:
return
false
,
true
default
:
panic
(
"unknown basic type"
)
}
default
:
panic
(
"basic type is expected"
)
}
}
func
getTypeStr
(
from
types
.
Type
,
target
string
)
string
{
func
getTypeStr
(
from
types
.
Type
,
target
string
)
string
{
// feasible types on different targets
// feasible types on different targets
defInt
:=
map
[
string
]
string
{
defInt
:=
map
[
string
]
string
{
...
@@ -41,9 +64,9 @@ func getTypeStr(from types.Type, target string) string {
...
@@ -41,9 +64,9 @@ func getTypeStr(from types.Type, target string) string {
types
.
Uint32
:
"i32"
,
types
.
Uint32
:
"i32"
,
types
.
Int64
:
"i64"
,
types
.
Int64
:
"i64"
,
types
.
Uint64
:
"i64"
,
types
.
Uint64
:
"i64"
,
types
.
Float32
:
"f
32
"
,
types
.
Float32
:
"f
loat
"
,
types
.
Float64
:
"
f64
"
,
types
.
Float64
:
"
double
"
,
types
.
UntypedFloat
:
"f
32
"
,
types
.
UntypedFloat
:
"f
loat
"
,
}
}
switch
t
:=
from
.
(
type
)
{
switch
t
:=
from
.
(
type
)
{
...
@@ -68,3 +91,24 @@ func getTypeStr(from types.Type, target string) string {
...
@@ -68,3 +91,24 @@ func getTypeStr(from types.Type, target string) string {
panic
(
"unknown type"
)
panic
(
"unknown type"
)
}
}
}
}
func
getValueStr
(
val
ssa
.
Value
)
string
{
switch
val
.
(
type
)
{
case
*
ssa
.
Const
:
name
:=
val
.
Name
()
if
pos
:=
strings
.
Index
(
name
,
":"
);
pos
>
0
{
name
=
name
[
0
:
pos
]
// Special form for float32/float64 constants as LLVM-IR requested.
if
isFloat
,
_
:=
checkType
(
val
.
Type
());
isFloat
{
if
f
,
err
:=
strconv
.
ParseFloat
(
name
,
64
);
err
==
nil
{
name
=
fmt
.
Sprintf
(
"%e"
,
f
)
}
}
}
return
name
case
*
ssa
.
Parameter
:
return
"%"
+
val
.
Name
()
default
:
return
"%"
+
val
.
Name
()
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录