Start work on forbble2.

Keep the old version around for now.
Add (indexOf) and (split) to lib.pbl
Distinct addToEnv() and setInEnv().
Add .clangd to gitignore.
This commit is contained in:
Sage Vaillancourt 2022-04-18 15:36:54 -04:00 committed by Sage Vaillancourt
parent 04b7e7b64a
commit 4ea3b1d36d
9 changed files with 142 additions and 9 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ pl
node_modules/
.idea/
.clangd/

View File

@ -78,9 +78,12 @@ Object fetchFromEnvironment(const char* name, struct Environment* env)
throw(DID_NOT_FIND_SYMBOL, "%s", name);
}
void addToEnv(struct Environment* env, const char* name, const Object obj)
void setVar(struct Environment* env, const char* name, const Object obj, int recurse)
{
struct StrippedObject* existing = fetch(name, env);
struct StrippedObject* existing = recurse
? fetch(name, env)
: getFromTable(&env->table, name);
if (existing) {
Object o = deStrip(*existing);
cleanObject(&o);
@ -92,6 +95,16 @@ void addToEnv(struct Environment* env, const char* name, const Object obj)
addToTable(&env->table, strdup(name), cloneObject(obj));
}
void addToEnv(struct Environment* env, const char* name, const Object obj)
{
setVar(env, name, obj, 0);
}
void setInEnv(struct Environment* env, const char* name, const Object obj)
{
setVar(env, name, obj, 1);
}
/**
* Build the local Environment for a given lambda
* @param params List of symbol objects with the names of lambda params
@ -168,6 +181,7 @@ struct Environment defaultEnv()
struct symFunc symFuncs[] = {
pf(def),
pf(set),
pf(add),
pf(sub),
pf(mul),

View File

@ -35,6 +35,8 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
void addToEnv(struct Environment* env, const char* name, Object obj);
void setInEnv(struct Environment* env, const char* name, Object obj);
void printEnv(struct Environment* env, int printPointers);
void addFunc(const char* name,

72
src/examples/forbble2.pbl Normal file
View File

@ -0,0 +1,72 @@
#!/usr/bin/pl
; Initialize an empty stack
(def stack ())
(def stkadd (fn (a)
"Add the given value to the stack"
(set stack (pre stack a))
))
(def pop (fn ()
"Remove the top of the stack"
(if (> (len stack) 0) (
(def top (at 0 stack))
(set stack (rest stack))
top
) (prn "pop: STACK EMPTY"))
))
(def twop (fn (op)
"Apply the given operation to the top two stack elements" (
(if (< (len stack) 2) ()
(stkadd (op (pop) (pop)))
))))
(def swap (fn () (
(def top (pop))
(def bottom (pop))
(stkadd top)
(stkadd bottom)
)))
(def words (fn (text) (
(split text " ")
)))
(def pstack (fn () (
(prnl (cat "Stack: " stack))
)))
(def e (fn (code) (
(eval code)
)))
(def loud-pop (fn () (
(prnl (pop))
)))
(def fmap (fn (word) (
;(prnl (cat "fmap: " word))
(if (= "swap" word) (swap)
(if (= "??" word) (pstack)
(if (= "+" word) (twop +)
(if (= "-" word) (twop -)
(if (= "/" word) (twop /)
(if (= "*" word) (twop *)
(if (= "." word) (loud-pop)
(stkadd (eval word))
)))))))
)))
(def repl (fn () (
(def z (inp "plf:> "))
(if (= z "q") () (
(for-each fmap (words z))
(prn nl)
(repl)
))
)))
(repl)

View File

@ -1,7 +1,4 @@
#!/usr/bin/pl
; Print with newline
(def esc (ch 27))
(def string (fn (a) (cat "" a)))
(def nl (ch 10))
@ -11,6 +8,25 @@
(prn (cat _txt nl))
)))
(def _indexOf (fn (txt search) (
(if (startsWith txt search) 0
(+ 1 (_indexOf (substr 1 9999999 txt) search))
)
)))
(def indexOf (fn (txt search) (
(def i (_indexOf txt search))
(if (> i (slen txt)) (- 0 1) i)
)))
(def split (fn (txt splitter)
"Split a string at each instance of splitter" (
(def i (indexOf txt splitter))
(if (< i 0) (txt)
(pre (split (substr (+ 1 i) 9999999 txt) splitter) (substr 0 i txt))
)
)))
(def loadfile (fn (file-name)
"Read and immediately evaluate the file with the given path." (
(eval (rf file-name))
@ -52,7 +68,7 @@
(def for-each (fn (action list)
"Apply the given action to each element in list." (
(map f list)
(map action list)
""
)))

View File

@ -7,6 +7,8 @@
(def cyan "")
(def white "")
(def esc (ch 27))
(def bold "")
(def reset "")
(def ~ (env "HOME"))

View File

@ -254,8 +254,7 @@ int main(int argc, const char* argv[])
if (settings.configFile) {
sprintf(config, "%s", settings.configFile);
} else {
const char* const home = getenv("HOME");
sprintf(config, "%s/.pebblisp.pbl", home);
sprintf(config, "%s/.pebblisp.pbl", getenv("HOME"));
}
if (readFile(config, &env) == 1 && settings.configFile) {
fprintf(stderr, "Config file not found at %s\n", config);

View File

@ -33,6 +33,18 @@ Object def(Object* params, unused int length, unused struct Environment* env)
return cloneObject(params[0]);
}
Object set(Object* params, unused int length, unused struct Environment* env)
{
const char* name = params[0].string;
Object finalValue = eval(&params[1], env);
setInEnv(env, name, finalValue);
cleanObject(&finalValue);
return cloneObject(params[0]);
}
/**
* Add a struct to the environment with a given name and fields.
*
@ -396,7 +408,8 @@ Result readSeq(struct Slice* tokens)
tokens = r.slices;
cleanObject(&r.obj);
forceString = next->text[0] == '?'
|| (strncmp(next->text, "def", 3) == 0);
|| (strncmp(next->text, "def", 3) == 0)
|| (strncmp(next->text, "setVar", 3) == 0);
}
}
@ -598,6 +611,14 @@ char* readFileToString(FILE* input)
int c;
int i = 1; // Skip refCount
if ((c = fgetc(input)) == '#') {
do {
c = fgetc(input);
} while (c != '\n' && c != EOF);
} else {
string[i++] = c;
}
while ((c = fgetc(input)) != EOF) {
string[i] = c;
i++;

View File

@ -123,6 +123,12 @@ fn(def, "def",
"(def x 10) x", "10",
);
fn(set, "set",
"Set the value for a variable.\n"
"Only defines a new variable if an existing one cannot be found.",
"(set x 10) x", "10",
);
tfn(structAccess, "poss",
({ expect(isStruct), anyType, anyType }),
"Get the value of a struct's field",