func builtinFun(context *runtime.MacroCallContext) (*runtime.Value, error) { argNodes := context.Nodes[0].(*parser.ListNode) var args []string callback := context.Nodes[1].(*parser.ListNode) if len(callback.Nodes) == 0 { return nil, runtime.NewRuntimeError(callback.Pos(), "empty function body") } for _, argNode := range argNodes.Nodes { ident, ok := argNode.(*parser.IdentifierNode) if !ok { return nil, runtime.NewRuntimeError(argNode.Pos(), "expected an identifier") } args = append(args, ident.Token.Data) } function := runtime.NewLambdaFunction([]parser.Node{callback}, args) return runtime.NewFunctionValue(function), nil }
func builtinDefun(context *runtime.MacroCallContext) (*runtime.Value, error) { name := context.Nodes[0].(*parser.IdentifierNode).Token.Data if name == "_" { return nil, runtime.NewRuntimeError(context.Nodes[0].Pos(), "disallowed function name") } if context.Block.Scope.GetSymbol(name) != nil && context.Block.Scope.GetSymbol(name).Const { return nil, runtime.NewRuntimeError(context.Nodes[0].Pos(), "%s is a constant and cannot be modified", name) } argNodes := context.Nodes[1].(*parser.ListNode) var args []string callback := context.Nodes[2].(*parser.ListNode) if len(callback.Nodes) == 0 { return nil, runtime.NewRuntimeError(callback.Pos(), "empty function body") } for _, argNode := range argNodes.Nodes { ident, ok := argNode.(*parser.IdentifierNode) if !ok { return nil, runtime.NewRuntimeError(argNode.Pos(), "expected an identifier") } args = append(args, ident.Token.Data) } function := runtime.NewDeclaredFunction([]parser.Node{callback}, name, args) functionValue := runtime.NewFunctionValue(function) context.Block.Scope.SetSymbol(name, runtime.NewSymbol(functionValue)) return functionValue, nil }
package builtin import ( "fmt" "github.com/raoulvdberge/risp/lexer" "github.com/raoulvdberge/risp/parser" "github.com/raoulvdberge/risp/runtime" "github.com/raoulvdberge/risp/util" "math/big" ) var Symbols = runtime.Symtab{ "t": runtime.NewSymbol(runtime.True), "f": runtime.NewSymbol(runtime.False), "nil": runtime.NewSymbol(runtime.Nil), "print": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinPrint, "print"))), "println": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinPrintln, "println"))), "list": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinList, "list"))), "string": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinString, "string"))), "+": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMath, "+"))), "-": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMath, "-"))), "*": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMath, "*"))), "/": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMath, "/"))), "=": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinEquals, "="))), "!=": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinNotEquals, "!="))), ">": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMathCmp, ">"))), ">=": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMathCmp, ">="))), "<": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMathCmp, "<"))), "<=": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinMathCmp, "<="))), "and": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinAnd, "and"))), "or": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(builtinOr, "or"))),
package strings import ( "github.com/raoulvdberge/risp/runtime" "github.com/raoulvdberge/risp/util" "strings" "unicode" ) var Symbols = runtime.Symtab{ "range": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsRange, "range"))), "trim": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsTrim, "trim"))), "rune-at": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsRuneAt, "rune-at"))), "length": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsLength, "length"))), "format": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsFormat, "format"))), "split": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsSplit, "split"))), "replace": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsReplace, "replace"))), "reverse": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsReverse, "reverse"))), "contains": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsContains, "contains"))), "lower": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsLower, "lower"))), "upper": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsUpper, "upper"))), "is-digit": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsCharacterCheck, "is-digit"))), "is-letter": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsCharacterCheck, "is-letter"))), "is-lower": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsCharacterCheck, "is-lower"))), "is-upper": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(stringsCharacterCheck, "is-upper"))), } func stringsRange(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.StringValue, runtime.NumberValue, runtime.NumberValue); err != nil { return nil, err }
package math import ( "github.com/raoulvdberge/risp/runtime" "math" ) var Symbols = runtime.Symtab{ "mod": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathMod, "mod"))), "sqrt": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "sqrt"))), "sin": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "sin"))), "cos": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "cos"))), "tan": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "tan"))), "ceil": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "ceil"))), "floor": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "floor"))), "abs": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "abs"))), "log": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "log"))), "log10": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathSimpleMath, "log10"))), "pow": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathPow, "pow"))), "deg2rad": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathDeg2Rad, "deg2rad"))), "rad2deg": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(mathRad2Deg, "rad2deg"))), "pi": runtime.NewSymbol(runtime.NewNumberValueFromFloat64(math.Pi)), "e": runtime.NewSymbol(runtime.NewNumberValueFromFloat64(math.E)), } func mathMod(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.NumberValue, runtime.NumberValue); err != nil { return nil, err } return runtime.NewNumberValueFromInt64(context.Args[0].NumberToInt64() % context.Args[1].NumberToInt64()), nil
package list import "github.com/raoulvdberge/risp/runtime" var Symbols = runtime.Symtab{ "seq": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listSeq, "seq"))), "contains": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listContains, "contains"))), "contains-key": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listContainsKey, "contains-key"))), "push": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listPush, "push"))), "push-left": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listPushLeft, "push-left"))), "size": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listSize, "size"))), "get": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listGet, "get"))), "get-key": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listGetKey, "get-key"))), "set": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listSet, "set"))), "set-key": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listSetKey, "set-key"))), "drop": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listDrop, "drop"))), "drop-left": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listDropLeft, "drop-left"))), "join": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listJoin, "join"))), "range": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listRange, "range"))), "reverse": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listReverse, "reverse"))), "remove": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listRemove, "remove"))), "remove-key": runtime.NewSymbol(runtime.NewFunctionValue(runtime.NewBuiltinFunction(listRemoveKey, "remove-key"))), } func listSeq(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.NumberValue, runtime.NumberValue); err != nil { return nil, err } low := context.Args[0].NumberToInt64() high := context.Args[1].NumberToInt64()