mirror of
https://gitee.com/wa-lang/wa.git
synced 2025-12-06 17:19:15 +08:00
wire 支持一元表达式
This commit is contained in:
@@ -374,8 +374,7 @@ func (b *Builder) expr(e ast.Expr, block *wire.Block) wire.Value {
|
||||
var v wire.Value
|
||||
if tv.Addressable() {
|
||||
loc := b.location(e, false, block)
|
||||
typ := b.BuildType(deref(tv.Type))
|
||||
v = block.EmitLoad(loc, typ, int(e.Pos()))
|
||||
v = block.EmitLoad(loc, loc.DataType(), int(e.Pos()))
|
||||
} else {
|
||||
v = b.expr0(e, tv, block)
|
||||
}
|
||||
@@ -399,12 +398,37 @@ func (b *Builder) expr0(e ast.Expr, tv types.TypeAndValue, block *wire.Block) wi
|
||||
|
||||
if _, ok := obj.(*types.Var); ok {
|
||||
loc := block.Lookup(obj, false)
|
||||
typ := b.BuildType(obj.Type())
|
||||
return block.EmitLoad(loc, typ, int(obj.Pos()))
|
||||
return block.EmitLoad(loc, loc.DataType(), int(obj.Pos()))
|
||||
}
|
||||
|
||||
// 函数
|
||||
panic("Todo")
|
||||
// :*ast.Ident
|
||||
|
||||
case *ast.UnaryExpr:
|
||||
switch e.Op {
|
||||
case token.AND: // &x, 逃逸
|
||||
loc := b.location(e.X, true, block)
|
||||
if _, ok := unparen(e.X).(*ast.StarExpr); ok {
|
||||
// Todo: p 为空时,&*p 应panic
|
||||
}
|
||||
return loc
|
||||
case token.ADD: // +x, 等价于x
|
||||
return b.expr(e.X, block)
|
||||
case token.NOT:
|
||||
x := b.expr(e.X, block)
|
||||
return block.EmitUnopNot(x, int(e.OpPos))
|
||||
case token.SUB:
|
||||
x := b.expr(e.X, block)
|
||||
return block.EmitUnopSub(x, int(e.OpPos))
|
||||
case token.XOR:
|
||||
x := b.expr(e.X, block)
|
||||
return block.EmitUnopXor(x, int(e.OpPos))
|
||||
|
||||
default:
|
||||
panic(e.Op)
|
||||
} // :*ast.UnaryExpr
|
||||
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unexpected expr: %T", e))
|
||||
|
||||
@@ -5,9 +5,12 @@ package spinner
|
||||
|
||||
import (
|
||||
"wa-lang.org/wa/internal/ast"
|
||||
"wa-lang.org/wa/internal/ast/astutil"
|
||||
"wa-lang.org/wa/internal/types"
|
||||
)
|
||||
|
||||
func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }
|
||||
|
||||
// 判断 e 是否为 "_"
|
||||
func isBlankIdent(e ast.Expr) bool {
|
||||
id, ok := e.(*ast.Ident)
|
||||
|
||||
@@ -146,6 +146,33 @@ func (b *Block) EmitReturn(results []Value, pos int) *InstReturn {
|
||||
return v
|
||||
}
|
||||
|
||||
func (b *Block) EmitUnopNot(x Value, pos int) *InstUnopNot {
|
||||
v := &InstUnopNot{X: x}
|
||||
v.Stringer = v
|
||||
v.pos = pos
|
||||
|
||||
b.emit(v)
|
||||
return v
|
||||
}
|
||||
|
||||
func (b *Block) EmitUnopSub(x Value, pos int) *InstUnopSub {
|
||||
v := &InstUnopSub{X: x}
|
||||
v.Stringer = v
|
||||
v.pos = pos
|
||||
|
||||
b.emit(v)
|
||||
return v
|
||||
}
|
||||
|
||||
func (b *Block) EmitUnopXor(x Value, pos int) *InstUnopXor {
|
||||
v := &InstUnopXor{X: x}
|
||||
v.Stringer = v
|
||||
v.pos = pos
|
||||
|
||||
b.emit(v)
|
||||
return v
|
||||
}
|
||||
|
||||
// Emit
|
||||
func (b *Block) EmitBlock(comment string, pos int) *Block {
|
||||
block := &Block{}
|
||||
|
||||
@@ -110,3 +110,39 @@ func (i *InstReturn) String() string {
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
/**************************************
|
||||
InstUnopNot: 一元非指令
|
||||
**************************************/
|
||||
type InstUnopNot struct {
|
||||
aImv
|
||||
X Value
|
||||
}
|
||||
|
||||
func (i *InstUnopNot) String() string {
|
||||
return fmt.Sprintf("!%s", i.X.Name())
|
||||
}
|
||||
|
||||
/**************************************
|
||||
InstUnopSub: 取负指令
|
||||
**************************************/
|
||||
type InstUnopSub struct {
|
||||
aImv
|
||||
X Value
|
||||
}
|
||||
|
||||
func (i *InstUnopSub) String() string {
|
||||
return fmt.Sprintf("-%s", i.X.Name())
|
||||
}
|
||||
|
||||
/**************************************
|
||||
InstUnopXor: 一元异或指令
|
||||
**************************************/
|
||||
type InstUnopXor struct {
|
||||
aImv
|
||||
X Value
|
||||
}
|
||||
|
||||
func (i *InstUnopXor) String() string {
|
||||
return fmt.Sprintf("^%s", i.X.Name())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user