Adds mod-path proc and fixes how string escapes work so that we store the raw string and only convert when needed. Less lightweight, but allows for better representation that remains true to the input when using write-raw

master
sloum 2 years ago
parent 096a3ab852
commit 3353de9de6

@ -328,7 +328,7 @@ Not implemented, but on my radar:
Implemented:
`exit`, `license`, `apply`, `!`, `exception-mode-panic`, `exception-mode-pass`, `term-size`, `term-restore`, `term-char-mode`, `term-raw-mode`, `term-cooked-mode`, `term-sane-mode`, `signal-catch-sigint`, `exception-mode-pass?`, `exception-mode-panic?`
`exit`, `license`, `apply`, `!`, `exception-mode-panic`, `exception-mode-pass`, `term-size`, `term-restore`, `term-char-mode`, `term-raw-mode`, `term-cooked-mode`, `term-sane-mode`, `signal-catch-sigint`, `exception-mode-pass?`, `exception-mode-panic?`, `mod-path`
- `(license)` will print the license terms for slope, this is mostly input as a convenience in the repl.
- The various term modes are an experimental feature at the moment, but should work as described
@ -354,6 +354,7 @@ Implemented:
<li><code>(term-cooked-mode)</code>: <code>()</code></li>
<li><code>(term-sane-mode)</code>: <code>()</code></li>
<li><code>(signal-catch-sigint [procedure])</code>: <code>bool</code> The procedure passed to <code>signal-catch-sigint</code> should take no arguments and will be run upon sigint being received. This will override all default behavior (if you still want the program to exit you will need to call <code>(exit)</code> from within the procedure). This procedure (<code>signal-catch-sigint</code>) should be called at the root level of your program as it will only have access to the global environment.</li>
<li><code>(mod-path)</code>: <code>string</code></li>
</ul>
</details>

@ -196,9 +196,11 @@ func unescapeString(s string) string {
slash = false
if otherNum.Len() > 0 {
i, err := strconv.ParseInt(otherNum.String(), escapeNumBase, 0)
i, err := strconv.ParseInt(otherNum.String(), escapeNumBase, 64)
if err == nil {
out.WriteRune(rune(i))
} else {
out.WriteRune('?')
}
otherNum.Reset()
}
@ -214,6 +216,14 @@ func unescapeString(s string) string {
out.WriteRune(c)
}
}
if otherNum.Len() > 0 {
i, err := strconv.ParseInt(otherNum.String(), escapeNumBase, 64)
if err == nil {
out.WriteRune(rune(i))
} else {
out.WriteRune('?')
}
}
return out.String()
}

@ -16,9 +16,7 @@ func eval(exp expression, en *env) (value expression) {
switch e := exp.(type) {
case symbol:
value = en.Find(e).vars[e]
case string:
value = unescapeString(e)
case bool, number:
case bool, number, string:
value = e
case exception:
if panicOnException {

@ -35,6 +35,9 @@ var stdLibrary = vars{
openFiles = append(openFiles, dn)
return dn
}(),
"mod-path": func(a ...expression) expression {
return getModBaseDir()
},
"__SIGINT": func(a ...expression) expression {
SafeExit(1)
return false

@ -37,7 +37,7 @@ func RecoverError() {
}
}
func String(v expression, quoteString bool) string {
func String(v expression, rawString bool) string {
switch v := v.(type) {
case []expression:
l := make([]string, len(v))
@ -46,10 +46,10 @@ func String(v expression, quoteString bool) string {
}
return "(" + strings.Join(l, " ") + ")"
case string:
if quoteString {
if rawString {
return fmt.Sprintf("\"%s\"", v)
}
return v
return unescapeString(v)
case exception:
return string(v)
case bool:

@ -86,6 +86,7 @@ var usageStrings = map[string]string{
"member?": "(member? [list] [value]) => bool",
"min": "(min [number...]) => number",
"mkdir": "(mkdir [path: string] [permissions: number] [[make-all: bool]]) => ()",
"mod-path": "(mod-path) => string\n\nReturns the current module path. The module path is calculated each time, in order to detect changes. As such, this is more expensive than a runtime constant",
"mv": "(mv [from-path: string] [to-path: string]) => ()",
"negative?": "(negative? [number]) => bool",
"not": "(not [value]) => bool\n\n`not` will invert the truthiness of the value it is given",

Loading…
Cancel
Save