changes to print functions, other small changes

This commit is contained in:
Pekka Laiho 2020-12-14 08:22:22 +07:00
parent 7e146d8a9d
commit 56d9a1ff90
6 changed files with 38 additions and 24 deletions

View File

@ -534,17 +534,18 @@ while | yes | Control flow
### Core functions
Name | Safe-mode | Example | Example result | Description
----- | --------- | ------- | -------------- | -----------
debug | no | `(debug)` | `true` | Toggle debug output.
doc | yes | `(doc +)` | `"Return the sum of all arguments."` | Show the documentation string for a function.
| yes | `(doc myfn "Documentation string.")` | `"Documentation string."` | Set the documentation string for a function.
exit | no | `(exit 1)` | | Terminate the script with given exit code using [exit](https://www.php.net/manual/en/function.exit.php).
print | no | `(print "hello world")` | `hello world` | Print expression on the screen. Give optional second argument as `true` to show strings in readable format. Print returns null (shown in REPL).
pstr | yes | `(pstr {"a":"b"})` | `"{\"a\":\"b\"}"` | Print expression to string.
read | yes | `(read "(+ 1 2 3)")` | `(+ 1 2 3)` | Read a string as code and return the expression.
sleep | no | `(sleep 2000)` | `null` | Sleep for the given period given in milliseconds using [usleep](https://www.php.net/manual/en/function.usleep).
throw | yes | `(throw "invalid value")` | `error: "invalid value"` | Throw an exception. The given value is passed to catch. See the section Exceptions.
Name | Safe-mode | Example | Example result | Description
------ | --------- | ------- | -------------- | -----------
debug | no | `(debug)` | `true` | Toggle debug output.
doc | yes | `(doc +)` | `"Return the sum of all arguments."` | Show the documentation string for a function.
| yes | `(doc myfn "Documentation string.")` | `"Documentation string."` | Set the documentation string for a function.
exit | no | `(exit 1)` | | Terminate the script with given exit code using [exit](https://www.php.net/manual/en/function.exit.php).
print | no | `(print "hello world")` | `hello world` | Print expression on the screen.
printr | no | `(printr "hello world")` | `"hello world"` | Print expression on the screen in readable format.
prints | yes | `(prints "hello world")` | `"\"hello world\""` | Print expression to string in readable format.
read | yes | `(read "(+ 1 2 3)")` | `(+ 1 2 3)` | Read a string as code and return the expression.
sleep | no | `(sleep 2000)` | `null` | Sleep for the given period given in milliseconds using [usleep](https://www.php.net/manual/en/function.usleep).
throw | yes | `(throw "invalid value")` | `error: "invalid value"` | Throw an exception. The given value is passed to catch. See the section Exceptions.
### Collection functions

View File

@ -15,7 +15,8 @@
(defn cmdMod (args) (apply % args))
(defn cmdMul (args) (apply * args))
(defn cmdSub (args) (apply - args))
(defn cmdHelp (args) (str "Available commands: " (apply join ", " (keys cmdMap))))
(defn cmdHelp () (str "Available commands: " (apply join ", " (keys cmdMap))))
(defn cmdQuit () (exit))
;; And we define a hash-map for command lookups with minimum number of arguments
(def cmdMap {
@ -25,6 +26,7 @@
"mul": [cmdMul 2]
"sub": [cmdSub 2]
"help": [cmdHelp 0]
"quit": [cmdQuit 0]
})
;; Find the first command which starts with the given name, or null
@ -38,8 +40,8 @@
;; and call it, giving the rest of the words as arguments.
(defn parseInput (inp)
(let (words (split " " inp) cname (first words) args (tail words) cmd (findCmd cname))
(if (null? cmd) (print "Unknown command, try 'help'.")
(if (< (len args) (second cmd)) (print (str "Give at least 2 arguments to " cname "."))
(if (null? cmd) "Unknown command, try 'help'."
(if (< (len args) (second cmd)) (str "Give at least 2 arguments to " cname ".")
((first cmd) args)))))
;; Define a file for readline and load it
@ -51,4 +53,4 @@
(let (inp (readline "[calc] "))
(readline-add inp)
(readline-save readlineFile)
(print (str "⇒ " (parseInput inp) EOL))))
(print "⇒ " (parseInput inp) EOL)))

View File

@ -11,8 +11,8 @@
;; Return the string for defining the given function
(defn funcToStr (f name)
(str (if (macro? f) "(defmacro " "(defn ")
name " " (pstr (meta f "args")) " "
(pstr (meta f "body")) ")"))
name " " (prints (meta f "args")) " "
(prints (meta f "body")) ")"))
;; Write a hash-map of functions into a file
(defn dumpFuncs (funcs filename)

View File

@ -1,2 +1,2 @@
;; Measure how long it takes to execute f
(defn timer (f) (let (st (mtime)) (f) (- (mtime) st)))
(defn timeFn (f) (let (st (mtime)) (f) (- (mtime) st)))

View File

@ -212,8 +212,8 @@ class Evaller
return $env;
} elseif ($symbolName == 'eval') {
if ($astLength == 1) {
return null;
if ($astLength != 2) {
throw new MadLispException("eval requires exactly 1 argument");
}
$ast = $this->eval($astData[1], $env, $depth + 1);

View File

@ -69,15 +69,26 @@ class Core implements ILib
}
if (!$this->safemode) {
$env->set('print', new CoreFunc('print', 'Print argument. Give second argument as true to show strings in readable format.', 1, 2,
function ($a, bool $readable = false) {
$this->printer->print($a, $readable);
$env->set('print', new CoreFunc('print', 'Print arguments.', 0, -1,
function (...$args) {
foreach ($args as $a) {
$this->printer->print($a, false);
}
return null;
}
));
}
$env->set('pstr', new CoreFunc('pstr', 'Print argument to string.', 1, 1,
if (!$this->safemode) {
$env->set('printr', new CoreFunc('printr', 'Print argument in readable format.', 1, 1,
function ($a) {
$this->printer->print($a, true);
return null;
}
));
}
$env->set('prints', new CoreFunc('prints', 'Print argument in readable format to string.', 1, 1,
function ($a) {
return $this->printer->pstr($a, true);
}