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 {
|
func (c *Compiler) getWATType(t Type) string {
|
||||||
switch t.Type {
|
switch t.Type {
|
||||||
case Type_Primitive:
|
case Type_Primitive:
|
||||||
@ -212,6 +220,83 @@ func (c *Compiler) compileAssignmentExpressionWAT(assignment AssignmentExpressio
|
|||||||
panic("assignment expr not implemented")
|
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) {
|
func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -351,7 +436,16 @@ func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
|||||||
case UnaryOperation_LogicalNot:
|
case UnaryOperation_LogicalNot:
|
||||||
return wat + "i32.eqz\n", nil
|
return wat + "i32.eqz\n", nil
|
||||||
case UnaryOperation_PreIncrement, UnaryOperation_PreDecrement, UnaryOperation_PostIncrement, UnaryOperation_PostDecrement:
|
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:
|
case Expression_Cast:
|
||||||
cast := expr.Value.(CastExpression)
|
cast := expr.Value.(CastExpression)
|
||||||
@ -379,7 +473,7 @@ func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if raw.Type.Type == Type_Primitive {
|
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
|
return wat, nil
|
||||||
|
@ -20,3 +20,16 @@ u64 fib(u64 i) {
|
|||||||
|
|
||||||
return fibA;
|
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)
|
parsedFiles = append(parsedFiles, parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
validator := Validator{Files: parsedFiles}
|
validator := Validator{Files: parsedFiles, Wasm64: *wasm64}
|
||||||
errors := validator.validate()
|
errors := validator.validate()
|
||||||
if len(errors) != 0 {
|
if len(errors) != 0 {
|
||||||
for _, err := range errors {
|
for _, err := range errors {
|
||||||
@ -188,7 +188,14 @@ func main() {
|
|||||||
return
|
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
|
var input bytes.Buffer
|
||||||
input.Write([]byte(wat))
|
input.Write([]byte(wat))
|
||||||
|
Loading…
Reference in New Issue
Block a user