Skip to content

Commit

Permalink
Const array cast.
Browse files Browse the repository at this point in the history
  • Loading branch information
markkurossi committed Dec 11, 2023
1 parent 5d166b9 commit 40b7e52
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
54 changes: 54 additions & 0 deletions compiler/ast/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,60 @@ func (ast *Call) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
// Eval implements the compiler.ast.AST.Eval.
func (ast *ArrayCast) Eval(env *Env, ctx *Codegen, gen *ssa.Generator) (
ssa.Value, bool, error) {

typeInfo, err := ast.TypeInfo.Resolve(env, ctx, gen)
if err != nil {
return ssa.Undefined, false, err
}
if typeInfo.Type != types.TArray {
return ssa.Undefined, false,
ctx.Errorf(ast.Expr, "array cast to non-array type %v", typeInfo)
}

cv, ok, err := ast.Expr.Eval(env, ctx, gen)
if err != nil {
return ssa.Undefined, false, err
}
if !ok {
return ssa.Undefined, false, nil
}

switch cv.Type.Type {
case types.TString:
if cv.Type.Bits%8 != 0 {
return ssa.Undefined, false,
ctx.Errorf(ast.Expr, "invalid string length %v", cv.Type.Bits)
}
chars := cv.Type.Bits / 8
et := typeInfo.ElementType
if et.Bits != 8 || et.Type != types.TUint {
return ssa.Undefined, false,
ctx.Errorf(ast.Expr, "cast from %v to %v",
cv.Type, ast.TypeInfo)
}

if typeInfo.Concrete() {
if typeInfo.ArraySize != chars || typeInfo.Bits != cv.Type.Bits {
return ssa.Undefined, false,
ctx.Errorf(ast.Expr, "cast from %v to %v",
cv.Type, ast.TypeInfo)
}
} else {
typeInfo.Bits = cv.Type.Bits
typeInfo.ArraySize = chars
typeInfo.SetConcrete(true)
}
cast := cv
cast.Type = typeInfo
if cv.HashCode() != cast.HashCode() {
panic("const array cast changes value HashCode")
}
if !cv.Equal(&cast) {
panic("const array cast changes value equality")
}
return cast, true, nil
}

return ssa.Undefined, false, nil
}

Expand Down
11 changes: 11 additions & 0 deletions compiler/tests/const_cast_bytearr_string.mpcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// -*- go -*-

package main

// 0x48656c6c6f2c20776f726c6421

// @Test 42 1 = 0x21646c726f77202c6f6c6c6548
func main(a []byte, b int) []byte {
ret := []byte("Hello, world!")
return ret
}
13 changes: 13 additions & 0 deletions compiler/tests/const_cast_string_bytearr.mpcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// -*- go -*-

package main

// @Test 42 1 = 0x21646c726f77202c6f6c6c6548
func main(a []byte, b int) string {
val := []byte{
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77,
0x6f, 0x72, 0x6c, 0x64, 0x21,
}
ret := string(val)
return ret
}

0 comments on commit 40b7e52

Please sign in to comment.