Add pre-/post-increment/decrement expressions
This commit is contained in:
parent
e9074e1632
commit
157c0bf217
@ -91,6 +91,14 @@ func (c *Compiler) getAddressWATType() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Compiler) getEffectiveAddressType() PrimitiveType {
|
||||
if c.Wasm64 {
|
||||
return Primitive_U64
|
||||
} else {
|
||||
return Primitive_U32
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Compiler) getWATType(t Type) string {
|
||||
switch t.Type {
|
||||
case Type_Primitive:
|
||||
@ -212,6 +220,83 @@ func (c *Compiler) compileAssignmentExpressionWAT(assignment AssignmentExpressio
|
||||
panic("assignment expr not implemented")
|
||||
}
|
||||
|
||||
func (c *Compiler) compileAssignmentUpdateExpressionWAT(lhs Expression, updateWAT string, evaluateToOldValue bool) (string, error) {
|
||||
switch lhs.Type {
|
||||
case Expression_VariableReference:
|
||||
ref := lhs.Value.(VariableReferenceExpression)
|
||||
local := strconv.Itoa(getLocal(c.CurrentBlock, ref.Variable).Index)
|
||||
|
||||
exprWAT, err := c.compileExpressionWAT(lhs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var tmpLocal Local
|
||||
wat := exprWAT
|
||||
if evaluateToOldValue {
|
||||
tmpLocal = Local{Name: "", Type: *lhs.ValueType, IsParameter: false, Index: len(c.CurrentFunction.Locals)}
|
||||
c.CurrentFunction.Locals = append(c.CurrentFunction.Locals, tmpLocal)
|
||||
|
||||
wat += "local.tee $" + strconv.Itoa(tmpLocal.Index) + "\n"
|
||||
}
|
||||
|
||||
wat += updateWAT
|
||||
|
||||
if evaluateToOldValue {
|
||||
wat += "local.set $" + local + "\n"
|
||||
wat += "local.get $" + strconv.Itoa(tmpLocal.Index) + "\n"
|
||||
} else {
|
||||
wat += "local.tee $" + local + "\n"
|
||||
}
|
||||
|
||||
return wat, nil
|
||||
case Expression_ArrayAccess:
|
||||
panic("TODO") // TODO
|
||||
case Expression_RawMemoryReference:
|
||||
raw := lhs.Value.(RawMemoryReferenceExpression)
|
||||
|
||||
localAddress := Local{Name: "", Type: Type{Type: Type_Primitive, Value: c.getEffectiveAddressType()}, IsParameter: false, Index: len(c.CurrentFunction.Locals)}
|
||||
c.CurrentFunction.Locals = append(c.CurrentFunction.Locals, localAddress)
|
||||
|
||||
localValue := Local{Name: "", Type: *lhs.ValueType, IsParameter: false, Index: len(c.CurrentFunction.Locals)}
|
||||
c.CurrentFunction.Locals = append(c.CurrentFunction.Locals, localValue)
|
||||
|
||||
if raw.Type.Type != Type_Primitive {
|
||||
panic("TODO") //TODO
|
||||
}
|
||||
|
||||
addrWAT, err := c.compileExpressionWAT(raw.Address)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
wat := addrWAT
|
||||
|
||||
// dup address
|
||||
wat += "local.tee $" + strconv.Itoa(localAddress.Index) + "\n"
|
||||
wat += "local.get $" + strconv.Itoa(localAddress.Index) + "\n"
|
||||
|
||||
wat += c.getWATType(raw.Type) + ".load\n"
|
||||
|
||||
if evaluateToOldValue {
|
||||
wat += "local.tee $" + strconv.Itoa(localValue.Index) + "\n"
|
||||
}
|
||||
|
||||
wat += updateWAT
|
||||
|
||||
if !evaluateToOldValue {
|
||||
wat += "local.tee $" + strconv.Itoa(localValue.Index) + "\n"
|
||||
}
|
||||
|
||||
wat += c.getWATType(raw.Type) + ".store\n"
|
||||
wat += "local.get $" + strconv.Itoa(localValue.Index) + "\n"
|
||||
|
||||
return wat, nil
|
||||
}
|
||||
|
||||
panic("assignment expr not implemented")
|
||||
}
|
||||
|
||||
func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
||||
var err error
|
||||
|
||||
@ -351,7 +436,16 @@ func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
||||
case UnaryOperation_LogicalNot:
|
||||
return wat + "i32.eqz\n", nil
|
||||
case UnaryOperation_PreIncrement, UnaryOperation_PreDecrement, UnaryOperation_PostIncrement, UnaryOperation_PostDecrement:
|
||||
// TODO: implement
|
||||
valueType := c.getWATType(*unary.Value.ValueType)
|
||||
|
||||
updateWAT := valueType + ".const 1\n"
|
||||
if unary.Operation == UnaryOperation_PreIncrement || unary.Operation == UnaryOperation_PostIncrement {
|
||||
updateWAT += valueType + ".add\n"
|
||||
} else {
|
||||
updateWAT += valueType + ".sub\n"
|
||||
}
|
||||
|
||||
return c.compileAssignmentUpdateExpressionWAT(unary.Value, updateWAT, unary.Operation == UnaryOperation_PostIncrement || unary.Operation == UnaryOperation_PostDecrement)
|
||||
}
|
||||
case Expression_Cast:
|
||||
cast := expr.Value.(CastExpression)
|
||||
@ -379,7 +473,7 @@ func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
||||
}
|
||||
|
||||
if raw.Type.Type == Type_Primitive {
|
||||
wat += c.getWATType(raw.Type) + ".load\n"
|
||||
wat += c.getWATType(raw.Type) + ".load\n" // TODO: use load8/load16(_s/u) for smaller types
|
||||
}
|
||||
|
||||
return wat, nil
|
||||
|
@ -20,3 +20,16 @@ u64 fib(u64 i) {
|
||||
|
||||
return fibA;
|
||||
}
|
||||
|
||||
(u64, u64) add(u64 a) {
|
||||
u64 x = a++;
|
||||
return x, a;
|
||||
}
|
||||
|
||||
(u64, u64) tuple() {
|
||||
return 1u64, 2u64;
|
||||
}
|
||||
|
||||
u64 sub(u64 a) {
|
||||
return --raw(u64, 0xFFu64);
|
||||
}
|
||||
|
11
main.go
11
main.go
@ -151,7 +151,7 @@ func main() {
|
||||
parsedFiles = append(parsedFiles, parsed)
|
||||
}
|
||||
|
||||
validator := Validator{Files: parsedFiles}
|
||||
validator := Validator{Files: parsedFiles, Wasm64: *wasm64}
|
||||
errors := validator.validate()
|
||||
if len(errors) != 0 {
|
||||
for _, err := range errors {
|
||||
@ -188,7 +188,14 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
cmd := exec.Command("wat2wasm", "-o", *outputFile, "-")
|
||||
var command []string
|
||||
if *wasm64 {
|
||||
// TODO: wasm64 support is currently broken because x.load doesn't accept 64-bit addresses
|
||||
command = append(command, "--enable-memory64")
|
||||
}
|
||||
command = append(command, "-o", *outputFile, "-")
|
||||
|
||||
cmd := exec.Command("wat2wasm", command...)
|
||||
|
||||
var input bytes.Buffer
|
||||
input.Write([]byte(wat))
|
||||
|
Loading…
Reference in New Issue
Block a user