aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--interpreter.py35
2 files changed, 38 insertions, 0 deletions
diff --git a/README.md b/README.md
index 9722129..cfc43ec 100644
--- a/README.md
+++ b/README.md
@@ -42,9 +42,11 @@
- `(/ [num :number] [denom :number]) => :number`
### string
+ - `(first-char [arg :string]) => :string`
- `(concat [arg :string] [many :string]) => :string`
- `(join [arg :list] [join-val :string]) => :string`
- `(newline) => :string`
+ - `(rest-char [arg :string]) => :string`
- `(split [arg :string] [split-val :string]) => :list`
- `(strip [arg :string]) => :string`
@@ -94,6 +96,7 @@
- `(list-reverse [arg :list]) => :int`
- `(rest [arg :list]) => :any ; cdr`
- `(shuf [arg :list]) => :list ; shuffle the elements of the list`
+ - `(slice [arg :list] [start-idx :int] [[length :int]]) => :list`
- `(zip [arg1 :list] [arg2 :list]) => :list`
### "higher order"
diff --git a/interpreter.py b/interpreter.py
index dbf8c82..04160cd 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -712,3 +712,38 @@ def interpretExists(symbol, args, env):
return Literal(Path(file_or_dir.value).resolve().exists())
GLOBALS.register("exists?", Builtin(interpretExists, 1))
+
+def interpretFirstChar(symbol, args, env):
+ ev = evaluate(args[0], env)
+ if not isinstance(ev, Literal):
+ raise Exception("'first-char' expects a string")
+ if len(ev.value) == 0:
+ raise Exception("string is empty")
+ return Literal(ev.value[0])
+
+GLOBALS.register("first-char", Builtin(interpretFirstChar, 1))
+
+def interpretRestChar(symbol, args, env):
+ ev = evaluate(args[0], env)
+ if not isinstance(ev, Literal):
+ raise Exception("'rest-char' expects a string")
+ return Literal(ev.value[1:])
+
+GLOBALS.register("rest-char", Builtin(interpretRestChar, 1))
+
+def interpretSlice(symbol, args, env):
+ lst = evaluate(args[0], env)
+ if not isinstance(lst, List):
+ raise Exception("'slice' expects a list as its first argument")
+ idx = evaluate(args[1], env)
+ if not isinstance(idx, Literal):
+ raise Exception("'slice' expects an integer as its second argument")
+ if len(args) == 2:
+ return List(lst.args[idx.value - 1:])
+ length = evaluate(args[2], env)
+ if not isinstance(length, Literal):
+ raise Exception("'slice' expects an integer as its third argument")
+ diff = idx.value - 1 + length.value
+ return List(lst.args[idx.value - 1:diff])
+
+GLOBALS.register("slice", Builtin(interpretSlice, 2, 3))