aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Veresov <aleksey@veresov.pro>2021-01-06 01:37:05 +0300
committerAleksey Veresov <aleksey@veresov.pro>2021-01-06 01:37:05 +0300
commit672512b0a2b3b4ae88f204293f4379c1fbb79850 (patch)
treec29ef6c7de3917e1057b74d08092f551139a7499
parent1afd0cdc7820d9c3a9ae032ea40545d7d32bf9bf (diff)
downloadcsx-672512b0a2b3b4ae88f204293f4379c1fbb79850.tar
csx-672512b0a2b3b4ae88f204293f4379c1fbb79850.tar.xz
csx-672512b0a2b3b4ae88f204293f4379c1fbb79850.zip
Added interpreter.
-rw-r--r--examples/generated.csx2
-rw-r--r--examples/interpreter.csx211
-rw-r--r--examples/translator.c36
-rw-r--r--src/csx.c33
4 files changed, 265 insertions, 17 deletions
diff --git a/examples/generated.csx b/examples/generated.csx
index 62fd2eb..574152f 100644
--- a/examples/generated.csx
+++ b/examples/generated.csx
@@ -59,7 +59,7 @@
{ The Program }
-[output "Hello, I am Casey Shawn Exton. " "What is your name?" newline]
+[output "Hello, I am Casey Shawn Exton. What is your name?" newline]
[output "> "]
[set name [instr]]
[output "Nice to meet you, " name "." newline]
diff --git a/examples/interpreter.csx b/examples/interpreter.csx
new file mode 100644
index 0000000..f4e22dc
--- /dev/null
+++ b/examples/interpreter.csx
@@ -0,0 +1,211 @@
+{ Base Utilities }
+
+[set no [fn [x] [same x []]]]
+[set id [fn [arg] arg]]
+[set list [fn args args]]
+
+[set catrev [fn [a b] [if a [catrev [tail a] [pair [head a] b]] b]]]
+[set rev [fn [l] [catrev l []]]]
+[set cat [fn [a b] [catrev [rev a] b]]]
+
+[set map [fn [f l] [if l [pair [f [head l]] [map f [tail l]]]]]]
+[set reduce [fn [f l] [if [no l] [] [if [no [tail l]] [head l]
+ [f [head l] [reduce f [tail l]]]
+]]]]
+
+
+{ Input-Output }
+
+[set newline [str [list 10]]]
+
+[set outint [fn [n]
+ [set zero 48]
+ [set minus 45]
+ [if [< n 0]
+ [do [out minus] [outint [neg n]]]
+ [if [< n 10]
+ [out [+ zero n]]
+ [do
+ [outint [div n 10]]
+ [out [+ zero [mod n 10]]]
+ ]
+ ]
+ ]
+]]
+
+[set outstr [fn [str]
+ [set outstrat [fn [str i len] [if [no [same i len]] [do
+ [out [str i]]
+ [outstrat str [+ i 1] len]
+ ]]]]
+ [outstrat str 0 [len str]]
+]]
+
+[set output [fn objs [map [fn [obj] [if
+ [same [type obj] 'int] [outint obj]
+ [same [type obj] 'str] [outstr obj]
+]] objs]]]
+
+[set instrlist [fn []
+ [set c [in]]
+ [if [no [same c 10]] [pair c [instrlist]]]
+]]
+[set instr [fn [] [str [instrlist]]]]
+
+
+{ The Program }
+
+[set screenstr [fn [str]
+ [set outstrat [fn [str i len] [if [no [same i len]] [do
+ [if [same [str i] ["\\" 0]] [output "\\"]]
+ [if [same [str i] ["\"" 0]] [output "\\"]]
+ [out [str i]]
+ [outstrat str [+ i 1] len]
+ ]]]]
+ [outstrat str 0 [len str]]
+]]
+
+[set screenname [fn [str]
+ [set outstrat [fn [str i len] [if [no [same i len]] [do
+ [if [same [str i] ["\\" 0]] [output "\\"]]
+ [if [same [str i] [" " 0]] [output "\\"]]
+ [if [same [str i] ["[" 0]] [output "\\"]]
+ [if [same [str i] ["]" 0]] [output "\\"]]
+ [out [str i]]
+ [outstrat str [+ i 1] len]
+ ]]]]
+ [outstrat str 0 [len str]]
+]]
+
+[set writeeach [fn [l] [if l [do
+ [write [head l]]
+ [if [tail l] [do
+ [output " "]
+ [writeeach [tail l]]
+ ]]
+]]]]
+
+[set write [fn [obj] [if
+ [no obj] [output "[]"]
+ [same [type obj] 'int] [outint obj]
+ [same [type obj] 'str] [do [output "\""] [screenstr obj] [output "\""]]
+ [same [type obj] 'pair] [do [output "["] [writeeach obj] [output "]"]]
+ [same [type obj] 'name] [screenname [str obj]]
+ [same [type obj] 'base] [output "<base>"]
+ [same [type obj] 'int] [output obj]
+ [same [type obj] 'fn] [output "<fn>"]
+ [same [type obj] 'sx] [output "<sx>"]
+]]]
+
+
+[set linep [pair [] []]]
+
+[set readcomment [fn [] [if
+ [same [head [head linep]] ["}" 0]] [sethead linep [tail [head linep]]]
+ [same [head [head linep]] ["{" 0]] [do
+ [sethead linep [tail [head linep]]]
+ [readcomment]
+ [readcomment]
+ ]
+ [do
+ [sethead linep [tail [head linep]]]
+ [readcomment]
+ ]
+]]]
+
+[set pairlist [fn [l] [if l [if [tail l]
+ [pair [head l] [pairlist [tail l]]]
+ [head l]
+]]]]
+
+[set readlist [fn [] [if
+ [same [head [head linep]] ["]" 0]] [sethead linep [tail [head linep]]]
+ [same [head [head linep]] [" " 0]] [do
+ [sethead linep [tail [head linep]]]
+ [readlist]
+ ]
+ [do
+ [set res [readobj]]
+ [pair res [readlist]]
+ ]
+]]]
+
+[set readint [fn [num]
+ [if [head [head linep]] [if [< 47 [head [head linep]] 58] [do
+ [set newnum [+ [* 10 num] [head [head linep]] -48]]
+ [sethead linep [tail [head linep]]]
+ [readint newnum]
+ ] num] num]
+]]
+
+[set readname [fn []
+ [if [head [head linep]] [if [no [same [head [head linep]] [" " 0]]]
+ [if [no [same [head [head linep]] ["[" 0]]] [if [no [same [head [head linep]] ["]" 0]]] [do
+ [if [same [head [head linep]] ["\\" 0]] [sethead linep [tail [head linep]]]]
+ [set res [head [head linep]]]
+ [sethead linep [tail [head linep]]]
+ [pair res [readname]]
+ ]]]
+ ]]
+]]
+
+[set readstr [fn []
+ [if [head [head linep]] [if [no [same [head [head linep]] ["\"" 0]]][do
+ [if [same [head [head linep]] ["\\" 0]] [sethead linep [tail [head linep]]]]
+ [set res [head [head linep]]]
+ [sethead linep [tail [head linep]]]
+ [pair res [readstr]]
+ ] [sethead linep [tail [head linep]]]]]
+]]
+
+[set readobj [fn [] [if
+ [same [head [head linep]] ["{" 0]] [do
+ [sethead linep [tail [head linep]]]
+ [readcomment]
+ [readobj]
+ ]
+ [same [head [head linep]] [" " 0]] [do
+ [sethead linep [tail [head linep]]]
+ [readobj]
+ ]
+ [same [head [head linep]] ["[" 0]] [do
+ [sethead linep [tail [head linep]]]
+ [readlist]
+ ]
+ [same [head [head linep]] ["=" 0]] [if
+ [same [head [tail [head linep]]] ["[" 0]] [do
+ [sethead linep [tail [tail [head linep]]]]
+ [pairlist [readlist]]
+ ]
+ [name [str [readname]]]
+ ]
+ [same [head [head linep]] ["-" 0]] [if
+ [< 47 [head [tail [head linep]]] 58] [do
+ [sethead linep [tail [head linep]]]
+ [neg [readint 0]]
+ ]
+ [name [str [readname]]]
+ ]
+ [same [head [head linep]] ["'" 0]] [do
+ [sethead linep [tail [head linep]]]
+ [list quote [readobj]]
+ ]
+ [same [head [head linep]] ["\"" 0]] [do
+ [sethead linep [tail [head linep]]]
+ [str [readstr]]
+ ]
+ [< 47 [head [head linep]] 58] [readint 0]
+ [name [str [readname line]]]
+]]]
+
+[set read [fn [usercontext]
+ [output "> "]
+ [sethead linep [instrlist]]
+ [set res [run [readobj] usercontext]]
+ [write [head res]]
+ [output newline]
+ [read [tail res]]
+]]
+
+[output "-= CSX interpreter loaded =-" newline]
+[read [newcontext]]
diff --git a/examples/translator.c b/examples/translator.c
index 01920c9..26bd5ac 100644
--- a/examples/translator.c
+++ b/examples/translator.c
@@ -20,10 +20,11 @@ void name(char a)
printf("\")");
}
-void num(char a)
+void num(char a, char b)
{
printf("csx_int(");
if (a) putchar(a);
+ if (b) putchar(b);
c = getchar();
while (c != EOF && isdigit(c)) {
putchar(c);
@@ -32,6 +33,14 @@ void num(char a)
printf(")");
}
+void list()
+{
+ printf("csx_list(");
+ items();
+ printf("0)");
+ c = getchar();
+}
+
void pair()
{
if ((c = getchar()) == '[') {
@@ -42,12 +51,15 @@ void pair()
} else name('=');
}
-void list()
+void quote()
{
- printf("csx_list(");
- items();
- printf("0)");
+ printf("csx_list(csx_name(\"quote\"),");
c = getchar();
+ if (c == '[') list();
+ else if (c == '=') pair();
+ else if (c == '\'') quote();
+ else name(0);
+ printf(",0)");
}
void skip()
@@ -75,9 +87,9 @@ void items()
if (first) first = 0; else putchar(',');
if (c == '[') list();
else if (c == '-')
- if (isdigit(c = getchar())) num('-');
+ if (isdigit(c = getchar())) num('-', c);
else name('-');
- else if (isdigit(c)) num(c);
+ else if (isdigit(c)) num(c, 0);
else if (c == '=') pair();
else if (c == '"') {
printf("csx_str(\"");
@@ -90,14 +102,8 @@ void items()
}
printf("\")");
c = getchar();
- } else if (c == '\'') {
- printf("csx_list(csx_name(\"quote\"),");
- c = getchar();
- if (c == '[') list();
- else if (c == '=') pair();
- else name(0);
- printf(",0)");
- } else name(0);
+ } else if (c == '\'') quote();
+ else name(0);
skip();
}
if (!first) putchar(',');
diff --git a/src/csx.c b/src/csx.c
index 0f07713..f114114 100644
--- a/src/csx.c
+++ b/src/csx.c
@@ -190,6 +190,7 @@ static void *base_is_set(void *arg)
static void *base_sethead(void *arg)
{
+ arg = run_each(arg);
pair_data *p = head(arg);
p->head = head(tail(arg));
return null;
@@ -197,6 +198,7 @@ static void *base_sethead(void *arg)
static void *base_settail(void *arg)
{
+ arg = run_each(arg);
pair_data *p = head(arg);
p->tail = head(tail(arg));
return null;
@@ -421,6 +423,18 @@ static void *base_len(void *arg)
return csx_int(len);
}
+static void *base_run(void *arg)
+{
+ arg = run_each(arg);
+ if (type(tail(arg)) == type_null) return csx_run(head(arg));
+ void *saved = context;
+ context = head(tail(arg));
+ void *res = csx_run(head(arg));
+ void *rescontext = context;
+ context = saved;
+ return new_pair(res, rescontext);
+}
+
static void *zip(void *params, void *values)
{
@@ -485,6 +499,21 @@ tailcall:
}
+static void *base_context(void *args)
+{
+ return context;
+}
+
+static void new_context();
+static void *base_newcontext(void *args)
+{
+ void *saved = context;
+ new_context();
+ void *res = context;
+ context = saved;
+ return res;
+}
+
static void new_context()
{
context = new_pair(null, null);
@@ -515,7 +544,9 @@ static void new_context()
base_set(csx_list(csx_name("name"), csx_base(base_name), 0));
base_set(csx_list(csx_name("str"), csx_base(base_str), 0));
base_set(csx_list(csx_name("len"), csx_base(base_len), 0));
- base_set(csx_list(csx_name("run"), csx_base(csx_run), 0));
+ base_set(csx_list(csx_name("run"), csx_base(base_run), 0));
+ base_set(csx_list(csx_name("context"), csx_base(base_context), 0));
+ base_set(csx_list(csx_name("newcontext"), csx_base(base_newcontext), 0));
}
static void init()