wire 支持一元表达式

This commit is contained in:
DingErNan
2025-11-25 18:00:24 +08:00
parent 7b7445775b
commit 23d440c67d
4 changed files with 94 additions and 4 deletions

View File

@@ -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))

View File

@@ -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)

View File

@@ -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{}

View File

@@ -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())
}