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:
parent
04b7e7b64a
commit
4ea3b1d36d
|
@ -9,3 +9,4 @@ pl
|
|||
|
||||
node_modules/
|
||||
.idea/
|
||||
.clangd/
|
||||
|
|
18
src/env.c
18
src/env.c
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
""
|
||||
)))
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
(def cyan "[36m")
|
||||
(def white "[37m")
|
||||
|
||||
(def esc (ch 27))
|
||||
|
||||
(def bold "[1m")
|
||||
(def reset "[0m")
|
||||
(def ~ (env "HOME"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(¶ms[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++;
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue