EvalApplyFn evaluates a built-in function application.
(applyFn ast.ApplyFn, subst ast.Subst)
| 102 | |
| 103 | // EvalApplyFn evaluates a built-in function application. |
| 104 | func EvalApplyFn(applyFn ast.ApplyFn, subst ast.Subst) (ast.Constant, error) { |
| 105 | evaluatedArgs, err := EvalExprs(applyFn.Args, subst) |
| 106 | if err != nil { |
| 107 | return ast.Constant{}, err |
| 108 | } |
| 109 | switch applyFn.Function.Symbol { |
| 110 | case symbols.Append.Symbol: |
| 111 | if l := len(evaluatedArgs); l != 2 { |
| 112 | return ast.Constant{}, fmt.Errorf("expected 2 list arguments, got %d argument(s)", l) |
| 113 | } |
| 114 | listElems, err := evaluatedArgs[0].ListSeq() |
| 115 | if err != nil { |
| 116 | return ast.Constant{}, fmt.Errorf("expected list got %v (%v) in %v (subst %v)", evaluatedArgs[0], evaluatedArgs[0].Type, applyFn, subst) |
| 117 | } |
| 118 | elem := evaluatedArgs[1] |
| 119 | var res []ast.Constant |
| 120 | for c := range listElems { |
| 121 | res = append(res, c) |
| 122 | } |
| 123 | res = append(res, elem) |
| 124 | return ast.List(res), nil |
| 125 | |
| 126 | case symbols.ListContains.Symbol: // fn:list:contains(List, Member) |
| 127 | if l := len(evaluatedArgs); l != 2 { |
| 128 | return ast.Constant{}, fmt.Errorf("expected 2 list arguments, got %d argument(s)", l) |
| 129 | } |
| 130 | listElems, err := evaluatedArgs[0].ListSeq() |
| 131 | if err != nil { |
| 132 | return ast.Constant{}, fmt.Errorf("expected list got %v (%v) in %v (subst %v)", evaluatedArgs[0], evaluatedArgs[0].Type, applyFn, subst) |
| 133 | } |
| 134 | elem := evaluatedArgs[1] |
| 135 | for c := range listElems { |
| 136 | if c.Equals(elem) { |
| 137 | return ast.TrueConstant, nil |
| 138 | } |
| 139 | } |
| 140 | return ast.FalseConstant, nil |
| 141 | |
| 142 | case symbols.Cons.Symbol: |
| 143 | if l := len(evaluatedArgs); l != 2 { |
| 144 | return ast.Constant{}, fmt.Errorf("expected 2 list arguments, got %d argument(s)", l) |
| 145 | } |
| 146 | fst := evaluatedArgs[0] |
| 147 | snd := evaluatedArgs[1] |
| 148 | if snd.Type != ast.ListShape { |
| 149 | return ast.Constant{}, fmt.Errorf("second argument has to be a list, got %v", snd.Type) |
| 150 | } |
| 151 | return ast.ListCons(&fst, &snd), nil |
| 152 | |
| 153 | case symbols.Pair.Symbol: |
| 154 | if l := len(evaluatedArgs); l != 2 { |
| 155 | return ast.Constant{}, fmt.Errorf("expected 2 list arguments, got %d argument(s)", l) |
| 156 | } |
| 157 | fst := evaluatedArgs[0] |
| 158 | snd := evaluatedArgs[1] |
| 159 | return ast.Pair(&fst, &snd), nil |
| 160 | |
| 161 | case symbols.Len.Symbol: |