func buildString(b *builder, op *lex8.Token) tast.Expr { v, e := strconv.Unquote(op.Lit) if e != nil { b.Errorf(op.Pos, "invalid string: %s", e) return nil } ref := tast.NewConstRef(types.String, v) return &tast.Const{ref} }
func buildChar(b *builder, op *lex8.Token) tast.Expr { v, e := strconv.Unquote(op.Lit) if e != nil { b.Errorf(op.Pos, "invalid char: %s", e) return nil } else if len(v) != 1 { b.Errorf(op.Pos, "invalid char in quote: %q", v) return nil } ref := tast.NewConstRef(types.Int8, int64(v[0])) return &tast.Const{ref} }
func buildInt(b *builder, op *lex8.Token) tast.Expr { ret, e := strconv.ParseInt(op.Lit, 0, 64) if e != nil { b.Errorf(op.Pos, "invalid integer: %s", e) return nil } if ret < math.MinInt32 { b.Errorf(op.Pos, "integer too small to fit in 32-bit") return nil } else if ret > math.MaxUint32 { b.Errorf(op.Pos, "integer too large to fit in 32-bit") return nil } ref := tast.NewConstRef(types.NewNumber(ret), ret) return &tast.Const{ref} }
func buildArrayLit(b *builder, lit *ast.ArrayLiteral) tast.Expr { hold := b.lhsSwap(false) defer b.lhsRestore(hold) if lit.Type.Len != nil { b.Errorf( ast.ExprPos(lit), "array literal with length not supported yet", ) return nil } buf := new(bytes.Buffer) t := buildType(b, lit.Type.Type) if t == nil { return nil } if !types.IsInteger(t) { pos := ast.ExprPos(lit.Type.Type) b.Errorf(pos, "array literal must be integer type") return nil } bt := t.(types.Basic) if lit.Exprs != nil { for _, expr := range lit.Exprs.Exprs { n := b.buildConstExpr(expr) if n == nil { return nil } ntype := n.R().T if _, ok := ntype.(*types.Const); !ok { b.Errorf(ast.ExprPos(expr), "array literal not a constant") return nil } if v, ok := types.NumConst(ntype); ok { if !types.InRange(v, t) { b.Errorf( ast.ExprPos(expr), "constant out of range of %s", t, ) return nil } switch bt { case types.Int, types.Uint: var bs [4]byte binary.LittleEndian.PutUint32(bs[:], uint32(v)) buf.Write(bs[:]) case types.Int8, types.Uint8: buf.Write([]byte{byte(v)}) default: panic("not integer") } } } } ref := tast.NewConstRef(&types.Slice{bt}, buf.Bytes()) return &tast.Const{ref} }