klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit a7031fb36626cda9e2fa0e9f9c199d549792b1e8
parent 4b95c140de6d6ac0803c29ae3d086cee0d54334a
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Tue, 22 Mar 2011 23:47:49 -0300

Added make-string to the ground environment.

Diffstat:
Msrc/Makefile | 8++++++--
Msrc/kghelpers.h | 3++-
Msrc/kground.c | 40+++++++++++++++++++++-------------------
Asrc/kgstrings.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/kgstrings.h | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kstring.c | 24++++++++++++++++++++----
Msrc/kstring.h | 2++
7 files changed, 232 insertions(+), 26 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -14,7 +14,8 @@ CORE_O= kobject.o ktoken.o kpair.o kstring.o ksymbol.o kread.o \ kground.o kghelpers.o kgbooleans.o kgeqp.o kgequalp.o \ kgsymbols.o kgcontrol.o kgpairs_lists.o kgpair_mut.o kgenvironments.o \ kgenv_mut.o kgcombiners.o kgcontinuations.o kgencapsulations.o \ - kgpromises.o kgkd_vars.o kgks_vars.o kgports.o kgchars.o kgnumbers.o + kgpromises.o kgkd_vars.o kgks_vars.o kgports.o kgchars.o kgnumbers.o \ + kgstrings.o KRN_T= klisp KRN_O= klisp.o @@ -80,7 +81,7 @@ kground.o: kground.c kground.h kstate.h kobject.h klisp.h kenvironment.h \ kgbooleans.h kgeqp.h kgequalp.h kgsymbols.h kgpairs_lists.h \ kgpair_mut.h kgenvironments.h kgenv_mut.h kgcombiners.h \ kgcontinuations.h kgencapsulations.h kgpromises.h kgkd_vars.h \ - kgks_vars.h kgports.h kgchars.h kgnumbers.h + kgks_vars.h kgports.h kgchars.h kgnumbers.h kgstrings.o kghelpers.o: kghelpers.c kghelpers.h kstate.h kstate.h klisp.h kpair.h \ kapplicative.h koperative.h kerror.h kobject.h ksymbol.h kgbooleans.o: kgbooleans.c kgbooleans.c kghelpers.h kstate.h klisp.h \ @@ -130,3 +131,6 @@ kgchars.o: kgchars.c kgchars.h kghelpers.h kstate.h klisp.h \ kgnumbers.o: kgnumbers.c kgnumbers.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h \ ksymbol.h +kgstrings.o: kgstrings.c kgstrings.h kghelpers.h kstate.h klisp.h \ + kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h \ + ksymbol.h diff --git a/src/kghelpers.h b/src/kghelpers.h @@ -177,7 +177,8 @@ inline bool get_opt_tpar(klisp_State *K, char *name, int32_t type, TValue *par) return true; } } else { - klispE_throw(K, "apply: Bad ptree structure (in optional argument)"); + klispE_throw_extra(K, name, ": Bad ptree structure (in optional " + "argument)"); /* avoid warning */ return false; } diff --git a/src/kground.c b/src/kground.c @@ -35,9 +35,10 @@ #include "kgpromises.h" #include "kgkd_vars.h" #include "kgks_vars.h" -#include "kgports.h" -#include "kgchars.h" #include "kgnumbers.h" +#include "kgstrings.h" +#include "kgchars.h" +#include "kgports.h" /* ** BEWARE: this is highly unhygienic, it assumes variables "symbol" and @@ -577,63 +578,64 @@ void kinit_ground_env(klisp_State *K) ** 13.1 Primitive features */ - /* 13.1.? string? */ + /* 13.1.1? string? */ add_applicative(K, ground_env, "string?", typep, 2, symbol, i2tv(K_TSTRING)); - /* 13.1.? make-string */ - /* TODO */ + /* 13.1.2? make-string */ + add_applicative(K, ground_env, "make-string", kgmake_string, 2, symbol, + i2tv(K_TSTRING)); - /* 13.1.? string-length */ + /* 13.1.3? string-length */ /* TODO */ - /* 13.1.? string-ref */ + /* 13.1.4? string-ref */ /* TODO */ - /* 13.1.? string-set! */ + /* 13.1.5? string-set! */ /* TODO */ /* ** 13.2 Library features */ - /* 13.2.? string */ + /* 13.2.1? string */ /* TODO */ - /* 13.2.? string=?, string-ci=? */ + /* 13.2.2? string=?, string-ci=? */ /* TODO */ - /* 13.2.? string<?, string<=?, string>?, string>=? */ + /* 13.2.3? string<?, string<=?, string>?, string>=? */ /* TODO */ - /* 13.2.? string-ci<?, string-ci<=?, string-ci>?, string-ci>=? */ + /* 13.2.4? string-ci<?, string-ci<=?, string-ci>?, string-ci>=? */ /* TODO */ - /* 13.2.? substring */ + /* 13.2.5? substring */ /* TODO */ - /* 13.2.? string-append */ + /* 13.2.6? string-append */ /* TODO */ - /* 13.2.? string->list, list->string */ + /* 13.2.7? string->list, list->string */ /* TODO */ - /* 13.2.? string-copy */ + /* 13.2.8? string-copy */ /* TODO */ - /* 13.2.? string-fill! */ + /* 13.2.9? string-fill! */ /* TODO */ /* ** 13.3 Symbol Features (this are from section symbol in r5rs) */ - /* 13.3.? symbol->string */ + /* 13.3.1? symbol->string */ /* TEMP: for now all strings are mutable, this returns a new object each time */ /* TODO */ - /* 13.3.? symbol->string */ + /* 13.3.2? symbol->string */ /* TEMP: for now this can create symbols with no external representation this includes all symbols with non identifiers characters. */ diff --git a/src/kgstrings.c b/src/kgstrings.c @@ -0,0 +1,101 @@ +/* +** kgstrings.c +** Strings features for the ground environment +** See Copyright Notice in klisp.h +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdint.h> +#include <ctype.h> + +#include "kstate.h" +#include "kobject.h" +#include "kapplicative.h" +#include "koperative.h" +#include "kcontinuation.h" +#include "kerror.h" +#include "ksymbol.h" +#include "kstring.h" + +#include "kghelpers.h" +#include "kgstrings.h" + +/* 13.1.1? string? */ +/* uses typep */ + +/* 13.1.2? make-string */ +void kgmake_string(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + bind_al1tp(K, "make-string", ptree, "finite number", ttisfixint, tv_s, + maybe_char); + + char fill = ' '; + if (get_opt_tpar(K, "make-string", K_TCHAR, &maybe_char)) + fill = chvalue(maybe_char); + + if (ivalue(tv_s) < 0) { + klispE_throw(K, "make-string: negative size"); + return; + } + + TValue new_str = kstring_new_sc(K, ivalue(tv_s), fill); + kapply_cc(K, new_str); +} + +/* 13.1.3? string-length */ +/* TODO */ + +/* 13.1.4? string-ref */ +/* TODO */ + +/* 13.1.5? string-set! */ +/* TODO */ + +/* 13.2.1? string */ +/* TODO */ + +/* 13.2.2? string=?, string-ci=? */ +/* TODO */ + +/* 13.2.3? string<?, string<=?, string>?, string>=? */ +/* TODO */ + +/* 13.2.4? string-ci<?, string-ci<=?, string-ci>?, string-ci>=? */ +/* TODO */ + +/* 13.2.5? substring */ +/* TODO */ + +/* 13.2.6? string-append */ +/* TODO */ + +/* 13.2.7? string->list, list->string */ +/* TODO */ + +/* 13.2.8? string-copy */ +/* TODO */ + +/* 13.2.9? string-fill! */ +/* TODO */ + +/* 13.3.1? symbol->string */ +/* TEMP: for now all strings are mutable, this returns a new object + each time */ +/* TODO */ + +/* 13.3.2? symbol->string */ +/* TEMP: for now this can create symbols with no external representation + this includes all symbols with non identifiers characters. +*/ +/* NOTE: + Symbols with uppercase alphabetic characters will write as lowercase and + so, when read again will not compare as either eq? or equal?. This is ok + because the report only says that read objects when written and read + again must be equal? which happens here +*/ +/* TODO */ diff --git a/src/kgstrings.h b/src/kgstrings.h @@ -0,0 +1,80 @@ +/* +** kgstrings.h +** Strings features for the ground environment +** See Copyright Notice in klisp.h +*/ + +#ifndef kgstrings_h +#define kgstrings_h + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdint.h> + +#include "kobject.h" +#include "klisp.h" +#include "kstate.h" +#include "kghelpers.h" + +/* 13.1.1? string? */ +/* uses typep */ + +/* 13.1.2? make-string */ +void kgmake_string(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); + +/* 13.1.3? string-length */ +/* TODO */ + +/* 13.1.4? string-ref */ +/* TODO */ + +/* 13.1.5? string-set! */ +/* TODO */ + +/* 13.2.1? string */ +/* TODO */ + +/* 13.2.2? string=?, string-ci=? */ +/* TODO */ + +/* 13.2.3? string<?, string<=?, string>?, string>=? */ +/* TODO */ + +/* 13.2.4? string-ci<?, string-ci<=?, string-ci>?, string-ci>=? */ +/* TODO */ + +/* 13.2.5? substring */ +/* TODO */ + +/* 13.2.6? string-append */ +/* TODO */ + +/* 13.2.7? string->list, list->string */ +/* TODO */ + +/* 13.2.8? string-copy */ +/* TODO */ + +/* 13.2.9? string-fill! */ +/* TODO */ + +/* 13.3.1? symbol->string */ +/* TEMP: for now all strings are mutable, this returns a new object + each time */ +/* TODO */ + +/* 13.3.2? symbol->string */ +/* TEMP: for now this can create symbols with no external representation + this includes all symbols with non identifiers characters. +*/ +/* NOTE: + Symbols with uppercase alphabetic characters will write as lowercase and + so, when read again will not compare as either eq? or equal?. This is ok + because the report only says that read objects when written and read + again must be equal? which happens here +*/ +/* TODO */ + +#endif diff --git a/src/kstring.c b/src/kstring.c @@ -35,7 +35,7 @@ TValue kstring_new_empty(klisp_State *K) } /* TEMP: for now all strings are mutable */ -TValue kstring_new(klisp_State *K, const char *buf, uint32_t size) +TValue kstring_new_g(klisp_State *K, uint32_t size) { String *new_str; @@ -55,14 +55,30 @@ TValue kstring_new(klisp_State *K, const char *buf, uint32_t size) /* string specific fields */ new_str->mark = KFALSE; new_str->size = size; - /* NOTE: there can be embedded '\0's in a string */ - memcpy(new_str->b, buf, size); - /* NOTE: they still end with a '\0' for convenience in printing */ + + /* the buffer is initialized elsewhere */ + + /* NOTE: all string end with a '\0' for convenience in printing + even if they have embedded '\0's */ new_str->b[size] = '\0'; return gc2str(new_str); } +TValue kstring_new(klisp_State *K, const char *buf, uint32_t size) +{ + TValue new_str = kstring_new_g(K, size); + memcpy(kstring_buf(new_str), buf, size); + return new_str; +} + +TValue kstring_new_sc(klisp_State *K, uint32_t size, char fill) +{ + TValue new_str = kstring_new_g(K, size); + memset(kstring_buf(new_str), fill, size); + return new_str; +} + /* both obj1 and obj2 should be strings! */ bool kstring_equalp(TValue obj1, TValue obj2) { diff --git a/src/kstring.h b/src/kstring.h @@ -16,6 +16,8 @@ TValue kstring_new_empty(klisp_State *K); TValue kstring_new(klisp_State *K, const char *buf, uint32_t size); +TValue kstring_new_sc(klisp_State *K, uint32_t size, char fill); + #define kstring_buf(tv_) (((String *) ((tv_).tv.v.gc))->b) #define kstring_size(tv_) (((String *) ((tv_).tv.v.gc))->size)