lang: funcs: Use constants for arg names

This commit is contained in:
James Shubin
2023-06-29 14:58:20 -04:00
parent f966b1ae6a
commit 97c7d176f0
7 changed files with 70 additions and 55 deletions

View File

@@ -30,6 +30,10 @@ const (
// starts with an underscore so that it cannot be used from the lexer. // starts with an underscore so that it cannot be used from the lexer.
// XXX: change to _contains and add syntax in the lexer/parser // XXX: change to _contains and add syntax in the lexer/parser
ContainsFuncName = "contains" ContainsFuncName = "contains"
// arg names...
containsArgNameNeedle = "needle"
containsArgNameHaystack = "haystack"
) )
func init() { func init() {
@@ -56,7 +60,7 @@ func (obj *ContainsPolyFunc) String() string {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *ContainsPolyFunc) ArgGen(index int) (string, error) { func (obj *ContainsPolyFunc) ArgGen(index int) (string, error) {
seq := []string{"needle", "haystack"} seq := []string{containsArgNameNeedle, containsArgNameHaystack}
if l := len(seq); index >= l { if l := len(seq); index >= l {
return "", fmt.Errorf("index %d exceeds arg length of %d", index, l) return "", fmt.Errorf("index %d exceeds arg length of %d", index, l)
} }
@@ -379,8 +383,8 @@ func (obj *ContainsPolyFunc) Stream() error {
} }
obj.last = input // store for next obj.last = input // store for next
needle := input.Struct()["needle"] needle := input.Struct()[containsArgNameNeedle]
haystack := (input.Struct()["haystack"]).(*types.ListValue) haystack := (input.Struct()[containsArgNameHaystack]).(*types.ListValue)
_, exists := haystack.Contains(needle) _, exists := haystack.Contains(needle)
var result types.Value = &types.BoolValue{V: exists} var result types.Value = &types.BoolValue{V: exists}

View File

@@ -32,7 +32,7 @@ const (
// FIXME: should this be named sprintf instead? // FIXME: should this be named sprintf instead?
PrintfFuncName = "printf" PrintfFuncName = "printf"
formatArgName = "format" // name of the first arg printfArgNameFormat = "format" // name of the first arg
) )
func init() { func init() {
@@ -68,10 +68,10 @@ func (obj *PrintfFunc) String() string {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *PrintfFunc) ArgGen(index int) (string, error) { func (obj *PrintfFunc) ArgGen(index int) (string, error) {
if index == 0 { if index == 0 {
return formatArgName, nil return printfArgNameFormat, nil
} }
// TODO: if index is big enough that it would return the string in // TODO: if index is big enough that it would return the string in
// `formatArgName` then we should return an error! (Nearly impossible.) // `printfArgNameFormat` then we should return an error! (Nearly impossible.)
return util.NumToAlpha(index - 1), nil return util.NumToAlpha(index - 1), nil
} }
@@ -186,7 +186,7 @@ func (obj *PrintfFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, erro
if err != nil { if err != nil {
return nil, err return nil, err
} }
if argName == formatArgName { if argName == printfArgNameFormat {
return nil, fmt.Errorf("could not build function with %d args", i+1) // +1 for format arg return nil, fmt.Errorf("could not build function with %d args", i+1) // +1 for format arg
} }
@@ -290,12 +290,12 @@ func (obj *PrintfFunc) Polymorphisms(partialType *types.Type, partialValues []ty
Out: types.TypeStr, Out: types.TypeStr,
} }
// add first arg // add first arg
typ.Map[formatArgName] = types.TypeStr typ.Map[printfArgNameFormat] = types.TypeStr
typ.Ord = append(typ.Ord, formatArgName) typ.Ord = append(typ.Ord, printfArgNameFormat)
for i, x := range typList { for i, x := range typList {
name := util.NumToAlpha(i) // start with a... name := util.NumToAlpha(i) // start with a...
if name == formatArgName { if name == printfArgNameFormat {
return nil, fmt.Errorf("could not build function with %d args", i+1) // +1 for format arg return nil, fmt.Errorf("could not build function with %d args", i+1) // +1 for format arg
} }
@@ -389,10 +389,10 @@ func (obj *PrintfFunc) Stream() error {
} }
obj.last = input // store for next obj.last = input // store for next
format := input.Struct()[formatArgName].Str() format := input.Struct()[printfArgNameFormat].Str()
values := []types.Value{} values := []types.Value{}
for _, name := range obj.Type.Ord { for _, name := range obj.Type.Ord {
if name == formatArgName { // skip format arg if name == printfArgNameFormat { // skip format arg
continue continue
} }
x := input.Struct()[name] x := input.Struct()[name]

View File

@@ -39,8 +39,9 @@ const (
// library. // library.
TemplateName = "template" TemplateName = "template"
argNameTemplate = "template" // arg names...
argNameVars = "vars" templateArgNameTemplate = "template"
templateArgNameVars = "vars"
) )
var ( var (
@@ -84,7 +85,7 @@ func (obj *TemplateFunc) String() string {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *TemplateFunc) ArgGen(index int) (string, error) { func (obj *TemplateFunc) ArgGen(index int) (string, error) {
seq := []string{argNameTemplate, argNameVars} seq := []string{templateArgNameTemplate, templateArgNameVars}
if l := len(seq); index >= l { if l := len(seq); index >= l {
return "", fmt.Errorf("index %d exceeds arg length of %d", index, l) return "", fmt.Errorf("index %d exceeds arg length of %d", index, l)
} }
@@ -184,7 +185,7 @@ func (obj *TemplateFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
if argName == argNameTemplate { if argName == templateArgNameTemplate {
return nil, fmt.Errorf("could not build function with %d args", 1) return nil, fmt.Errorf("could not build function with %d args", 1)
} }
@@ -259,7 +260,7 @@ func (obj *TemplateFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, er
// XXX: is there a better API than returning a buried `variant` type? // XXX: is there a better API than returning a buried `variant` type?
func (obj *TemplateFunc) Polymorphisms(partialType *types.Type, partialValues []types.Value) ([]*types.Type, error) { func (obj *TemplateFunc) Polymorphisms(partialType *types.Type, partialValues []types.Value) ([]*types.Type, error) {
// TODO: return `variant` as second arg for now -- maybe there's a better way? // TODO: return `variant` as second arg for now -- maybe there's a better way?
str := fmt.Sprintf("func(%s str, %s variant) str", argNameTemplate, argNameVars) str := fmt.Sprintf("func(%s str, %s variant) str", templateArgNameTemplate, templateArgNameVars)
variant := []*types.Type{types.NewType(str)} variant := []*types.Type{types.NewType(str)}
if partialType == nil { if partialType == nil {
@@ -281,11 +282,11 @@ func (obj *TemplateFunc) Polymorphisms(partialType *types.Type, partialValues []
} }
} }
if len(ord) == 1 { // no args being passed in (boring template) if len(ord) == 1 { // no args being passed in (boring template)
return []*types.Type{types.NewType(fmt.Sprintf("func(%s str) str", argNameTemplate))}, nil return []*types.Type{types.NewType(fmt.Sprintf("func(%s str) str", templateArgNameTemplate))}, nil
} else if t, exists := partialType.Map[ord[1]]; exists && t != nil { } else if t, exists := partialType.Map[ord[1]]; exists && t != nil {
// known vars type! w00t! // known vars type! w00t!
return []*types.Type{types.NewType(fmt.Sprintf("func(%s str, %s %s) str", argNameTemplate, argNameVars, t.String()))}, nil return []*types.Type{types.NewType(fmt.Sprintf("func(%s str, %s %s) str", templateArgNameTemplate, templateArgNameVars, t.String()))}, nil
} }
} }
@@ -348,11 +349,11 @@ func (obj *TemplateFunc) Validate() error {
func (obj *TemplateFunc) Info() *interfaces.Info { func (obj *TemplateFunc) Info() *interfaces.Info {
var sig *types.Type var sig *types.Type
if obj.NoVars { if obj.NoVars {
str := fmt.Sprintf("func(%s str) str", argNameTemplate) str := fmt.Sprintf("func(%s str) str", templateArgNameTemplate)
sig = types.NewType(str) sig = types.NewType(str)
} else if obj.Type != nil { // don't panic if called speculatively } else if obj.Type != nil { // don't panic if called speculatively
str := fmt.Sprintf("func(%s str, %s %s) str", argNameTemplate, argNameVars, obj.Type.String()) str := fmt.Sprintf("func(%s str, %s %s) str", templateArgNameTemplate, templateArgNameVars, obj.Type.String())
sig = types.NewType(str) sig = types.NewType(str)
} }
return &interfaces.Info{ return &interfaces.Info{
@@ -509,8 +510,8 @@ func (obj *TemplateFunc) Stream() error {
st := input.Struct() st := input.Struct()
tmpl := st[argNameTemplate].Str() tmpl := st[templateArgNameTemplate].Str()
vars, exists := st[argNameVars] vars, exists := st[templateArgNameVars]
if !exists { if !exists {
vars = nil vars = nil
} }

View File

@@ -56,8 +56,9 @@ const (
// keep this strict. // keep this strict.
StrictScheduleOpts = true StrictScheduleOpts = true
argNameNamespace = "namespace" // arg names...
argNameOpts = "opts" scheduleArgNameNamespace = "namespace"
scheduleArgNameOpts = "opts"
) )
func init() { func init() {
@@ -101,7 +102,7 @@ func (obj *SchedulePolyFunc) validOpts() map[string]*types.Type {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *SchedulePolyFunc) ArgGen(index int) (string, error) { func (obj *SchedulePolyFunc) ArgGen(index int) (string, error) {
seq := []string{argNameNamespace, argNameOpts} // 2nd arg is optional seq := []string{scheduleArgNameNamespace, scheduleArgNameOpts} // 2nd arg is optional
if l := len(seq); index >= l { if l := len(seq); index >= l {
return "", fmt.Errorf("index %d exceeds arg length of %d", index, l) return "", fmt.Errorf("index %d exceeds arg length of %d", index, l)
} }
@@ -272,8 +273,8 @@ func (obj *SchedulePolyFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant
} }
invariants = append(invariants, invar) invariants = append(invariants, invar)
mapped[argNameOpts] = dummyOpts mapped[scheduleArgNameOpts] = dummyOpts
ordered = append(ordered, argNameOpts) ordered = append(ordered, scheduleArgNameOpts)
} }
invar = &interfaces.EqualityWrapFuncInvariant{ invar = &interfaces.EqualityWrapFuncInvariant{
@@ -544,13 +545,13 @@ func (obj *SchedulePolyFunc) Stream() error {
} }
obj.last = input // store for next obj.last = input // store for next
namespace := input.Struct()[argNameNamespace].Str() namespace := input.Struct()[scheduleArgNameNamespace].Str()
if namespace == "" { if namespace == "" {
return fmt.Errorf("can't use an empty namespace") return fmt.Errorf("can't use an empty namespace")
} }
opts := make(map[string]types.Value) // empty "struct" opts := make(map[string]types.Value) // empty "struct"
if val, exists := input.Struct()[argNameOpts]; exists { if val, exists := input.Struct()[scheduleArgNameOpts]; exists {
opts = val.Struct() opts = val.Struct()
} }

View File

@@ -29,6 +29,10 @@ const (
// HistoryFuncName is the name this function is registered as. This // HistoryFuncName is the name this function is registered as. This
// starts with an underscore so that it cannot be used from the lexer. // starts with an underscore so that it cannot be used from the lexer.
HistoryFuncName = "_history" HistoryFuncName = "_history"
// arg names...
historyArgNameValue = "value"
historyArgNameIndex = "index"
) )
func init() { func init() {
@@ -66,7 +70,7 @@ func (obj *HistoryFunc) String() string {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *HistoryFunc) ArgGen(index int) (string, error) { func (obj *HistoryFunc) ArgGen(index int) (string, error) {
seq := []string{"value", "index"} seq := []string{historyArgNameValue, historyArgNameIndex}
if l := len(seq); index >= l { if l := len(seq); index >= l {
return "", fmt.Errorf("index %d exceeds arg length of %d", index, l) return "", fmt.Errorf("index %d exceeds arg length of %d", index, l)
} }
@@ -376,8 +380,8 @@ func (obj *HistoryFunc) Stream() error {
//} //}
//obj.last = input // store for next //obj.last = input // store for next
index := int(input.Struct()["index"].Int()) index := int(input.Struct()[historyArgNameIndex].Int())
value := input.Struct()["value"] value := input.Struct()[historyArgNameValue]
var result types.Value var result types.Value
if index < 0 { if index < 0 {

View File

@@ -31,9 +31,10 @@ const (
// XXX: change to _maplookup and add syntax in the lexer/parser // XXX: change to _maplookup and add syntax in the lexer/parser
MapLookupFuncName = "maplookup" MapLookupFuncName = "maplookup"
argNameMap = "map" // arg names...
argNameKey = "key" mapLookupArgNameMap = "map"
argNameDef = "default" mapLookupArgNameKey = "key"
mapLookupArgNameDef = "default"
) )
func init() { func init() {
@@ -60,7 +61,7 @@ func (obj *MapLookupPolyFunc) String() string {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *MapLookupPolyFunc) ArgGen(index int) (string, error) { func (obj *MapLookupPolyFunc) ArgGen(index int) (string, error) {
seq := []string{argNameMap, argNameKey, argNameDef} seq := []string{mapLookupArgNameMap, mapLookupArgNameKey, mapLookupArgNameDef}
if l := len(seq); index >= l { if l := len(seq); index >= l {
return "", fmt.Errorf("index %d exceeds arg length of %d", index, l) return "", fmt.Errorf("index %d exceeds arg length of %d", index, l)
} }
@@ -433,20 +434,20 @@ func (obj *MapLookupPolyFunc) Polymorphisms(partialType *types.Type, partialValu
typFunc := &types.Type{ typFunc := &types.Type{
Kind: types.KindFunc, // function type Kind: types.KindFunc, // function type
Map: make(map[string]*types.Type), Map: make(map[string]*types.Type),
Ord: []string{argNameMap, argNameKey, argNameDef}, Ord: []string{mapLookupArgNameMap, mapLookupArgNameKey, mapLookupArgNameDef},
Out: nil, Out: nil,
} }
typFunc.Map[argNameMap] = typ typFunc.Map[mapLookupArgNameMap] = typ
typFunc.Map[argNameKey] = typ.Key typFunc.Map[mapLookupArgNameKey] = typ.Key
typFunc.Map[argNameDef] = typ.Val typFunc.Map[mapLookupArgNameDef] = typ.Val
typFunc.Out = typ.Val typFunc.Out = typ.Val
// TODO: don't include partial internal func map's for now, allow in future? // TODO: don't include partial internal func map's for now, allow in future?
if typ.Key == nil || typ.Val == nil { if typ.Key == nil || typ.Val == nil {
typFunc.Map = make(map[string]*types.Type) // erase partial typFunc.Map = make(map[string]*types.Type) // erase partial
typFunc.Map[argNameMap] = types.TypeVariant typFunc.Map[mapLookupArgNameMap] = types.TypeVariant
typFunc.Map[argNameKey] = types.TypeVariant typFunc.Map[mapLookupArgNameKey] = types.TypeVariant
typFunc.Map[argNameDef] = types.TypeVariant typFunc.Map[mapLookupArgNameDef] = types.TypeVariant
} }
if typ.Val == nil { if typ.Val == nil {
typFunc.Out = types.TypeVariant typFunc.Out = types.TypeVariant
@@ -568,9 +569,9 @@ func (obj *MapLookupPolyFunc) Stream() error {
} }
obj.last = input // store for next obj.last = input // store for next
m := (input.Struct()[argNameMap]).(*types.MapValue) m := (input.Struct()[mapLookupArgNameMap]).(*types.MapValue)
key := input.Struct()[argNameKey] key := input.Struct()[mapLookupArgNameKey]
def := input.Struct()[argNameDef] def := input.Struct()[mapLookupArgNameDef]
var result types.Value var result types.Value
val, exists := m.Lookup(key) val, exists := m.Lookup(key)

View File

@@ -30,6 +30,10 @@ const (
// starts with an underscore so that it cannot be used from the lexer. // starts with an underscore so that it cannot be used from the lexer.
// XXX: change to _structlookup and add syntax in the lexer/parser // XXX: change to _structlookup and add syntax in the lexer/parser
StructLookupFuncName = "structlookup" StructLookupFuncName = "structlookup"
// arg names...
structLookupArgNameStruct = "struct"
structLookupArgNameField = "field"
) )
func init() { func init() {
@@ -58,7 +62,7 @@ func (obj *StructLookupPolyFunc) String() string {
// ArgGen returns the Nth arg name for this function. // ArgGen returns the Nth arg name for this function.
func (obj *StructLookupPolyFunc) ArgGen(index int) (string, error) { func (obj *StructLookupPolyFunc) ArgGen(index int) (string, error) {
seq := []string{"struct", "field"} seq := []string{structLookupArgNameStruct, structLookupArgNameField}
if l := len(seq); index >= l { if l := len(seq); index >= l {
return "", fmt.Errorf("index %d exceeds arg length of %d", index, l) return "", fmt.Errorf("index %d exceeds arg length of %d", index, l)
} }
@@ -369,15 +373,15 @@ func (obj *StructLookupPolyFunc) Polymorphisms(partialType *types.Type, partialV
typFunc := &types.Type{ typFunc := &types.Type{
Kind: types.KindFunc, // function type Kind: types.KindFunc, // function type
Map: make(map[string]*types.Type), Map: make(map[string]*types.Type),
Ord: []string{"struct", "field"}, Ord: []string{structLookupArgNameStruct, structLookupArgNameField},
Out: out, Out: out,
} }
typFunc.Map["struct"] = typ typFunc.Map[structLookupArgNameStruct] = typ
typFunc.Map["field"] = types.TypeStr typFunc.Map[structLookupArgNameField] = types.TypeStr
// set variant instead of nil // set variant instead of nil
if typFunc.Map["struct"] == nil { if typFunc.Map[structLookupArgNameStruct] == nil {
typFunc.Map["struct"] = types.TypeVariant typFunc.Map[structLookupArgNameStruct] = types.TypeVariant
} }
if out == nil { if out == nil {
typFunc.Out = types.TypeVariant typFunc.Out = types.TypeVariant
@@ -490,8 +494,8 @@ func (obj *StructLookupPolyFunc) Stream() error {
} }
obj.last = input // store for next obj.last = input // store for next
st := (input.Struct()["struct"]).(*types.StructValue) st := (input.Struct()[structLookupArgNameStruct]).(*types.StructValue)
field := input.Struct()["field"].Str() field := input.Struct()[structLookupArgNameField].Str()
if field == "" { if field == "" {
return fmt.Errorf("received empty field") return fmt.Errorf("received empty field")