aboutsummaryrefslogtreecommitdiff
path: root/r
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-12-18 20:33:49 -0600
committerJoel Martin <github@martintribe.org>2015-01-09 16:16:50 -0600
commitb8ee29b22fbaa7a01f2754b4d6dd9af52e02017c (patch)
treef4d977ed220e9a3f665cfbf4f68770a81e4c2095 /r
parentaaba249304b184e12e2445ab22d66df1f39a51a5 (diff)
downloadmal-b8ee29b22fbaa7a01f2754b4d6dd9af52e02017c.tar.gz
mal-b8ee29b22fbaa7a01f2754b4d6dd9af52e02017c.zip
All: add keywords.
Also, fix nth and count to match cloure.
Diffstat (limited to 'r')
-rw-r--r--r/core.r14
-rw-r--r--r/printer.r4
-rw-r--r--r/reader.r2
-rw-r--r--r/types.r5
4 files changed, 21 insertions, 4 deletions
diff --git a/r/core.r b/r/core.r
index 74c8f6d..dab36e3 100644
--- a/r/core.r
+++ b/r/core.r
@@ -46,6 +46,13 @@ cons <- function(a,b) {
new.listl(new_lst)
}
+nth <- function(a,b) {
+ if (b < length(a))
+ a[[b+1]]
+ else
+ throw("nth: index out of range")
+}
+
do_concat <- function(...) {
new_lst <- list()
for(l in list(...)) {
@@ -118,9 +125,10 @@ core_ns <- list(
"nil?"=.nil_q,
"true?"=.true_q,
"false?"=.false_q,
- "symbol?"=.symbol_q,
"symbol"=new.symbol,
"symbol?"=.symbol_q,
+ "keyword"=new.keyword,
+ "keyword?"=.keyword_q,
"pr-str"=pr_str,
"str"=str,
@@ -155,11 +163,11 @@ core_ns <- list(
"sequential?"=.sequential_q,
"cons"=cons,
"concat"=do_concat,
- "nth"=function(a,b) if (length(a) < b+1) nil else a[[b+1]],
+ "nth"=nth,
"first"=function(a) if (length(a) < 1) nil else a[[1]],
"rest"=function(a) new.listl(slice(a,2)),
"empty?"=function(a) .sequential_q(a) && length(a) == 0,
- "count"=function(a) length(a),
+ "count"=function(a) if (.nil_q(a)) 0 else length(a),
"apply"=do_apply,
"map"=map,
"conj"=conj,
diff --git a/r/printer.r b/r/printer.r
index e684b03..71deef7 100644
--- a/r/printer.r
+++ b/r/printer.r
@@ -27,7 +27,9 @@ if(!exists("..types..")) source("types.r")
paste("{", .pr_list(hlst, pr, " "), "}", sep="", collapse="")
},
"character"={
- if (print_readably) {
+ if (substring(exp,1,1) == "\u029e") {
+ concat(":", substring(exp,2))
+ } else if (print_readably) {
paste("\"",
gsub("\\n", "\\\\n",
gsub("\\\"", "\\\\\"",
diff --git a/r/reader.r b/r/reader.r
index 780dd4d..7f20288 100644
--- a/r/reader.r
+++ b/r/reader.r
@@ -46,6 +46,8 @@ read_atom <- function(rdr) {
gsub("\\\\n", "\\n",
gsub("\\\\\"", "\"",
substr(token, 2, nchar(token)-1)))
+ } else if (substr(token,1,1) == ":") {
+ new.keyword(substring(token,2))
} else if (token == "nil") {
nil
} else if (token == "true") {
diff --git a/r/types.r b/r/types.r
index 1f749a5..92d1357 100644
--- a/r/types.r
+++ b/r/types.r
@@ -80,7 +80,12 @@ nil <- structure("malnil", class="nil")
.true_q <- function(obj) "logical" == class(obj) && obj == TRUE
.false_q <- function(obj) "logical" == class(obj) && obj == FALSE
new.symbol <- function(name) structure(name, class="Symbol")
+
.symbol_q <- function(obj) "Symbol" == class(obj)
+new.keyword <- function(name) concat("\u029e", name)
+.keyword_q <- function(obj) {
+ "character" == class(obj) && "\u029e" == substr(obj,1,1)
+}
# Functions