205 lines
4.8 KiB
C
205 lines
4.8 KiB
C
#ifndef PEBBLISP_PLFUNC_H
|
|
#define PEBBLISP_PLFUNC_H
|
|
|
|
#include "pebblisp.h"
|
|
|
|
#define BASIC_OP(_name) \
|
|
Object _name(Object* params, int length, struct Environment* env)
|
|
|
|
BASIC_OP(add);
|
|
|
|
BASIC_OP(sub);
|
|
|
|
BASIC_OP(mul);
|
|
|
|
BASIC_OP(dvi);
|
|
|
|
BASIC_OP(mod);
|
|
|
|
BASIC_OP(equ);
|
|
|
|
BASIC_OP(greaterThan);
|
|
|
|
BASIC_OP(lessThan);
|
|
|
|
BASIC_OP(and);
|
|
|
|
BASIC_OP(or);
|
|
|
|
#undef BASIC_OP
|
|
|
|
tfn(catObjects, "cat",
|
|
({ NULL, isStringy }),
|
|
"Concatenate string representations of the given objects.",
|
|
"(cat \"Stuff: \" (1 2 3))", "Stuff: ( 1 2 3 )",
|
|
);
|
|
|
|
tfn(filter, "fil",
|
|
({ isFuncy, isListy, isListy }),
|
|
"Filter a list based on the given condition.",
|
|
"(fil (fn (a) (< 50 a)) (25 60 100))", "( 60 100 )",
|
|
"(fil (fn (a) (< 0 (len a))) ( () (1) (1 2) () ))", "( ( 1 ) ( 1 2 ) )",
|
|
);
|
|
|
|
tfn(append, "ap",
|
|
({ isListy, NULL, isListy }),
|
|
"Append the given element. Creates a new list.",
|
|
"(ap (1 2) 3)", "( 1 2 3 )",
|
|
);
|
|
|
|
tfn(prepend, "pre",
|
|
({ isListy, NULL, isListy }),
|
|
"Prepend the given element. Creates a new list",
|
|
"(pre (2 3) 1)", "( 1 2 3 )",
|
|
);
|
|
|
|
tfn(len, "len",
|
|
({ isListy, isNumber }),
|
|
"Returns the length of the given list, or an error if the expression is not a list.",
|
|
"(len (2 3))", "2",
|
|
"(len ())", "0",
|
|
"(len \"string\")", "BAD_PARAMS_ON: len",
|
|
);
|
|
|
|
tfn(reduce, "reduce",
|
|
({ NULL, isFuncy, NULL, NULL }),
|
|
"Performs a simple reduction. Does not currently work with lambdas.\n"
|
|
"Takes three arguments:\n"
|
|
" - Values\n"
|
|
" - A function to apply to each value\n"
|
|
" - An initial value",
|
|
"(reduce 5 + 6)", "11",
|
|
"(reduce (1 2 3) + 0)", "6",
|
|
);
|
|
|
|
tfn(at, "at",
|
|
({ isNumber, isListy, NULL }),
|
|
"Get item at the given index in the given list.",
|
|
"(at 1 (1 2 3))", "2",
|
|
"(at 99 (1 2 3))", "INDEX_PAST_END",
|
|
"(at 99 \"string\")", "BAD_PARAMS_ON: at",
|
|
);
|
|
|
|
tfn(rest, "rest",
|
|
({ isListy, isListy }),
|
|
"Get the tail of a list. All but the first element.",
|
|
"(rest (1 2 3))", "( 2 3 )",
|
|
"(rest ())", "( )",
|
|
"(rest \"string\")", "BAD_PARAMS_ON: rest",
|
|
);
|
|
|
|
tfn(reverse, "rev",
|
|
({ isListy, isListy }),
|
|
"Reverse a list.",
|
|
"(rev (1 2 3))", "( 3 2 1 )",
|
|
"(rev \"string\")", "BAD_PARAMS_ON: reverse",
|
|
);
|
|
|
|
tfn(isNum, "isnum",
|
|
({ NULL, isBool }),
|
|
"Returns `T` only if the argument evaluates to a number.",
|
|
"(isnum 1)", "T",
|
|
"(isnum (+ 5 5))", "T",
|
|
"(isnum '(+ 5 5))", "F",
|
|
"(isnum \"Hello\")", "F",
|
|
);
|
|
|
|
tfn(isList, "islist",
|
|
({ NULL, isBool }),
|
|
"Returns `T` only if the argument is a list.",
|
|
"(islist (1 2 3))", "T",
|
|
"(islist ())", "T",
|
|
"(islist \"Stringy\")", "F",
|
|
);
|
|
|
|
tfn(isString, "isstr",
|
|
({ NULL, isBool }),
|
|
"Returns `T` only if the argument is a string.",
|
|
"(isstr \"Heyo\")", "T",
|
|
"(isstr \"\")", "T",
|
|
"(isstr (cat 5 5))", "T",
|
|
"(isstr 10)", "F",
|
|
);
|
|
|
|
tfn(isErr, "iserr",
|
|
({ NULL, isBool }),
|
|
"Check if the argument is an error.",
|
|
"(iserr (at 10 ()))", "T",
|
|
"(iserr 5)", "F",
|
|
);
|
|
|
|
tfn(charAt, "chat",
|
|
({ isStringy, isNumber, isStringy }),
|
|
"Get the char in the given string at the given index.",
|
|
"(chat \"Hello\" 1)", "e",
|
|
"(chat \"Hello\" 10)", "",
|
|
);
|
|
|
|
tfn(charVal, "char",
|
|
({ isStringy, isNumber }),
|
|
"Get the ascii integer representaton of the given character.",
|
|
"(char \"h\")", "104",
|
|
"(char \"hello\")", "104",
|
|
"(char \"\")", "0",
|
|
);
|
|
|
|
/// STRING/SLIST => ANY
|
|
fn(parseEvalO, "eval",
|
|
"Evaluate the given string or quoted list.",
|
|
"(eval \"(1 2 3)\")", "( 1 2 3 )",
|
|
"(eval '(+ 5 5))", "10",
|
|
);
|
|
|
|
/// STRUCT, STRING => ANY
|
|
fn(possessive, "poss",
|
|
"(struct Post (title body))\n"
|
|
"(def p (Post \"TI\" \"BO\"))\n"
|
|
"p's title => TI"
|
|
);
|
|
|
|
#ifdef STANDALONE
|
|
|
|
fn(print, "prn", "Prints the string representation of the given object to stdout.");
|
|
|
|
tfn(numToChar, "ch",
|
|
({ isNumber, isStringy }),
|
|
"Gets a string containing the ascii character for the given number value.",
|
|
"(ch 107)", "k",
|
|
"(ch 0x21)", "!",
|
|
);
|
|
|
|
fn(printEnvO, "penv", "Prints out the current scoped environment.");
|
|
|
|
tfn(systemCall, "sys",
|
|
({ isStringy, isNumber }),
|
|
"Opens a shell and runs the given command, returning 0 if successful.\n"
|
|
"If the argument is not a string, returns 255.\n",
|
|
"(sys \"echo yee > /dev/null\")", "0",
|
|
);
|
|
|
|
tfn(loadFile, "loadfile",
|
|
({ isStringy, NULL }),
|
|
"Loads and parses the given file.\n"
|
|
"Returns 0 if the file was loaded and parsed successfully. Otherwise 1.\n"
|
|
"(loadfile \"printdate.pl\")\n"
|
|
"Mon 21 Mar 2022 10:35:03 AM EDT\n"
|
|
"=> 0"
|
|
);
|
|
|
|
/// @code
|
|
/// () => STRING
|
|
/// STRING => STRING
|
|
fn(takeInput, "inp",
|
|
"Take console input with an optional prompt. For example:\n"
|
|
"`(def x (input))` will wait for user input with no prompt.\n"
|
|
"`(def x (input \">> \"))` wait for input, but prompt the user with '>> '.\n"
|
|
);
|
|
|
|
tfn(readFileToObject, "rf",
|
|
({ isStringy, isStringy }),
|
|
"Read a file into a string object."
|
|
);
|
|
|
|
#endif // STANDALONE
|
|
|
|
#endif // PEBBLISP_PLFUNC_H
|