func prep(expr *ast.Expr, expType types.Type) (uniq string, err error) { if expr.Function != nil { fnc := expr.GetFunction() uniq, err = WhichFunc(fnc) if err != nil { return "", err } typ, err := funcs.Out(uniq) if err != nil { return "", err } if typ != expType { return "", &errExpected{expType.String(), expr.String()} } return uniq, err } if expr.List != nil { if !types.IsList(expType) { return "", &errExpected{expType.String(), expr.String()} } } typ, err := Which(expr) if err != nil { return "", err } if typ != expType { return "", &errExpected{expType.String(), expr.String()} } return "", nil }
func newValue(p *ast.Expr) (interface{}, error) { if p.Terminal != nil && p.GetTerminal().Variable != nil { return composeVariable(p.GetTerminal().Variable), nil } typ, err := Which(p) if err != nil { return nil, err } switch typ { case types.SINGLE_DOUBLE: return composeFloat64(p) case types.SINGLE_FLOAT: return composeFloat32(p) case types.SINGLE_INT64: return composeInt64(p) case types.SINGLE_UINT64: return composeUint64(p) case types.SINGLE_INT32: return composeInt32(p) case types.SINGLE_BOOL: return composeBool(p) case types.SINGLE_STRING: return composeString(p) case types.SINGLE_BYTES: return composeBytes(p) case types.SINGLE_UINT32: return composeUint32(p) case types.LIST_DOUBLE: return composeFloat64s(p) case types.LIST_FLOAT: return composeFloat32s(p) case types.LIST_INT64: return composeInt64s(p) case types.LIST_UINT64: return composeUint64s(p) case types.LIST_INT32: return composeInt32s(p) case types.LIST_BOOL: return composeBools(p) case types.LIST_STRING: return composeStrings(p) case types.LIST_BYTES: return composeListOfBytes(p) case types.LIST_UINT32: return composeUint32s(p) } panic("not implemented") }
func composeFloat32s(expr *ast.Expr) (funcs.Float32s, error) { uniq, err := prep(expr, types.LIST_FLOAT) if err != nil { return nil, err } if expr.List != nil { vs, err := newValues(expr.GetList().GetElems()) if err != nil { return nil, err } bs := make([]funcs.Float32, len(vs)) var ok bool for i := range vs { bs[i], ok = vs[i].(funcs.Float32) if !ok { return nil, &errExpected{types.SINGLE_FLOAT.String(), expr.String()} } } return funcs.NewListOfFloat32(bs), nil } values, err := newValues(expr.GetFunction().GetParams()) if err != nil { return nil, err } return funcs.NewFloat32sFunc(uniq, values...) }
func Which(expr *ast.Expr) (types.Type, error) { if expr.Terminal != nil { term := expr.GetTerminal() if term.DoubleValue != nil { return types.SINGLE_DOUBLE, nil } if term.FloatValue != nil { return types.SINGLE_FLOAT, nil } if term.Int64Value != nil { return types.SINGLE_INT64, nil } if term.Uint64Value != nil { return types.SINGLE_UINT64, nil } if term.Int32Value != nil { return types.SINGLE_INT32, nil } if term.BoolValue != nil { return types.SINGLE_BOOL, nil } if term.StringValue != nil { return types.SINGLE_STRING, nil } if term.BytesValue != nil { return types.SINGLE_BYTES, nil } if term.Uint32Value != nil { return types.SINGLE_UINT32, nil } if term.Variable != nil { return term.Variable.Type, nil } } if expr.List != nil { return expr.GetList().GetType(), nil } if expr.Function != nil { fnc := expr.GetFunction() uniq, err := WhichFunc(fnc) if err != nil { return 0, err } return funcs.Out(uniq) } return 0, &errUnknownType{expr} }
func composeFloat32(expr *ast.Expr) (funcs.Float32, error) { uniq, err := prep(expr, types.SINGLE_FLOAT) if err != nil { return nil, err } if expr.Terminal != nil { if expr.GetTerminal().Variable != nil { return funcs.NewFloat32Variable(), nil } else { return funcs.NewConstFloat32(expr.GetTerminal().GetFloatValue()), nil } } values, err := newValues(expr.GetFunction().GetParams()) if err != nil { return nil, err } return funcs.NewFloat32Func(uniq, values...) }
func composeBytes(expr *ast.Expr) (funcs.Bytes, error) { uniq, err := prep(expr, types.SINGLE_BYTES) if err != nil { return nil, err } if expr.Terminal != nil { if expr.GetTerminal().Variable != nil { return funcs.NewBytesVariable(), nil } else { return funcs.NewConstBytes(expr.GetTerminal().GetBytesValue()), nil } } values, err := newValues(expr.GetFunction().GetParams()) if err != nil { return nil, err } return funcs.NewBytesFunc(uniq, values...) }
func composeString(expr *ast.Expr) (funcs.String, error) { uniq, err := prep(expr, types.SINGLE_STRING) if err != nil { return nil, err } if expr.Terminal != nil { if expr.GetTerminal().Variable != nil { return funcs.NewStringVariable(), nil } else { return funcs.NewConstString(expr.GetTerminal().GetStringValue()), nil } } values, err := newValues(expr.GetFunction().GetParams()) if err != nil { return nil, err } return funcs.NewStringFunc(uniq, values...) }
func composeUint64(expr *ast.Expr) (funcs.Uint64, error) { uniq, err := prep(expr, types.SINGLE_UINT64) if err != nil { return nil, err } if expr.Terminal != nil { if expr.GetTerminal().Variable != nil { return funcs.NewUint64Variable(), nil } else { return funcs.NewConstUint64(expr.GetTerminal().GetUint64Value()), nil } } values, err := newValues(expr.GetFunction().GetParams()) if err != nil { return nil, err } return funcs.NewUint64Func(uniq, values...) }