diff --git a/.gitignore b/.gitignore
index b07b2a6..1968658 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,11 +38,3 @@ utils_src/readprintwc/out
src/io/fopen
hi\.*
-
-.vscode/
-
-core
-
-.kdev4/
-
-post-scarcity.kdev4
diff --git a/Makefile b/Makefile
index 7e5efb4..c4c4ef3 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ SRC_DIRS ?= ./src
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c -or -name *.s)
HDRS := $(shell find $(SRC_DIRS) -name *.h)
-OBJS := $(addsuffix .o,$(basename $(SRCS)))
+OBJS := $(addsuffix .o,$(basename $(SRCS)))
DEPS := $(OBJS:.o=.d)
TESTS := $(shell find unit-tests -name *.sh)
@@ -17,12 +17,11 @@ INDENT_FLAGS := -nbad -bap -nbc -br -brf -brs -c33 -cd33 -ncdb -ce -ci4 -cli4 \
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP -g -DDEBUG
LDFLAGS := -lm -lcurl
-DEBUGFLAGS := -g3
all: $(TARGET)
$(TARGET): $(OBJS) Makefile
- $(CC) $(DEBUGFLAGS) $(LDFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LOADLIBES) $(LDLIBS)
+ $(CC) $(LDFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LOADLIBES) $(LDLIBS)
doc: $(SRCS) Makefile Doxyfile
doxygen
@@ -39,7 +38,7 @@ test: $(OBJS) $(TESTS) Makefile
.PHONY: clean
clean:
- $(RM) $(TARGET) $(OBJS) $(DEPS) $(SRC_DIRS)/*~ $(SRC_DIRS)/*/*~ *~ core
+ $(RM) $(TARGET) $(OBJS) $(DEPS) $(SRC_DIRS)/*~ $(SRC_DIRS)/*/*~ *~
repl:
$(TARGET) -p 2> psse.log
diff --git a/README.md b/README.md
index 8ea4dc4..9c08aab 100644
--- a/README.md
+++ b/README.md
@@ -1,33 +1,11 @@
# Post Scarcity Software System, version 0
+Very Nearly a Big Lisp Environment
+
tl,dr: look at the [wiki](wiki).
## State of play
-### Version 0.0.5
-
-Has working Lisp interpreter, more or less complete, with functions and symbols as defined under [#bindings-currently-available](Bindings currently available) below. Features include hash maps.
-
-#### Known bugs
-
-At the time of writing, big number arithmetic is completely failing. It has worked in the past, but it doesn't now.
-
-There are ludicrous memory leaks. Essentially the garbage collection strategy isn't yet really working. However, if we are to implement the hypercube architecture in future, a mark and sweep garbage collector will not work, so it's important to get the reference counter working properly.
-
-#### Unknown bugs
-
-There are certainly MANY unknown bugs. Please report those you find.
-
-#### Not yet implemented
-
-1. There is as yet no **compiler**, and indeed it isn't yet certain what a compiler would even mean. Do all nodes in a machine necessarily share the same processor architecture?
-2. There's the beginnings of a narrative about how **namespaces** are going to work, but as yet they aren't really implemented.
-3. There is as yet no implementation of the concept of **users**. Access Control Lists exist but are not used. Related, there's no concept of a **session**.
-4. There is as yet no **multiprocessor architecture**, not even a simulated one. As it is intended that threading will be implemented by handing off parts of a computation to peer processors, this means there no **threads** either.
-5. There's no **user interface** beyond a REPL. There isn't even an **editor**, or **history**.
-6. **Printing to strings** does not work.
-7. The **exception system**, while it does exist, needs to be radically rethought.
-
### Version 0.0.4
Has working rational number arithmetic, as well as integer and real number arithmetic. The stack is now in vector space, but vector space is not yet properly garbage collected. `defun` does not yet work, so although Lisp functions can be defined the syntax is pretty clunky. So you *can* start to do things with this, but you should probably wait for at least a 0.1.0 release!
@@ -44,349 +22,6 @@ What I'm trying to do now is write a detailed low level specification of the und
Although I describe it as a 'Lisp environment', for reasons explained in Post Scarcity Software that doesn't mean you will program it in Lisp. It means that the underlying representation of things in the system is Lispy, not Unixy.
-## Bindings currently available
-
-The following symbols are bound in the bootstrap layer. It is anticipated that
-
-1. Most of the functions will be overridden by versions of the same function written in Lisp; but
-2. these implementations will remain available in the namespace `/:bootstrap`.
-
-### Values
-
-Note that symbols delimited by asterisks, as in `*in*`, invite rebinding; it is expected, for example, that users will want to rebind input and output streams in their current environment. Rebinding some other symbols, for example `nil`, is unwise.
-
-#### nil
-
-The canonical empty list.
-
-#### t
-
-The canonical true value.
-
-#### \*in\*
-
-The input stream.
-
-#### \*out\*
-
-The output stream.
-
-#### \*log\*
-
-The logging stream (equivalent to `stderr`).
-
-#### \*sink\*
-
-The sink stream (equivalent to `/dev/null`).
-
-#### \*prompt\*
-
-The REPL prompt.
-
-### Functions
-
-#### (absolute *n*)
-
-Return the absolute value of a number.
-
-#### (add *n1* *n2* ...), (+ *n1* *n2* ...)
-
-Return the result of adding together all the (assumed numeric) arguments supplied.
-
-#### (append *s1* *s2* ...)
-
-Return a new sequence comprising all the elements of *s1* followed by all the elements of *s2* and so on for an indefinite number of arguments. All arguments must be sequences of the same type.
-
-#### (apply *f* *s*)
-
-Apply the function *f* to the arguments that form the sequence *s*, and return the result.
-
-#### (assoc *key* *store*)
-
-Return the value associated with *key* in *store*. *key* may be an object of any type, but keywords, symbols and strings are handled most efficiently. *store* may be an [*association list*](#Association_list), or may be a hashmap.
-
-#### (car *s*)
-
-Return the first element of the sequence *s*.
-
-#### (cdr *s*)
-
-Return a sequence of all the elements of the sequence *s* except the first.
-
-#### (close *stream*)
-
-Closes the indicates stream. Returns `nil`.
-
-#### (cons *a* *b*)
-
-Returns a new pair comprising *a* and *b*. If *b* is a list, this has the effect of creating a new list with the element *a* prepended to all the elements of *b*. If *b* is `nil`, this has the effect creating a new list with *a* as the sole element. Otherwise, it just creates a pair.
-
-#### (divide *n1* *n2*), (/ *n1* *n2*)
-
-Divides the number *n1* by the number *n2*. If *n1* and *n2* are both integers, it's likely that the result will be a rational number.
-
-#### (eq *o1* *o2*)
-
-Returns true (`t`) if *o1* and *o2* are identically the same object, else `nil`.
-
-#### (equal *o1* *o2*), (= *o1* *o2*)
-
-Returns true (`t`) if *o1* and *o2* are structurally identical to one another, else `nil`.
-
-#### (exception *message*)
-
-Throws (returns) an exception, with the specified *message*. Note that this doesn't really work at all well, and that it is extremely likely this signature will change.
-
-#### (get-hash *key* *hashmap*)
-
-Like 'assoc', but the store must be a hashmap. Deprecated.
-
-#### (hashmap *n* *f* *store*)
-
-Create a hashmap with *n* buckets, using *f* as its hashing function, and initialised with the key/value pairs from *store*. All arguments are optional; if none are passed, will create an empty hashmap with 32 keys and the default hashing function.
-
-#### (inspect *o*)
-
-Prints detailed structure of the object *o*. Primarily for debugging.
-
-#### (keys *store*)
-
-Returns a list of the keys in *store*, which may be either an [*association list*](#Association_list), or a hashmap.
-
-#### (let *bindings* *form*...)
-
-Evaluates each of the *forms* in an environment to which ally of these *bindings* have been added. *bindings* must be an [*association list*](#Association_list), and, additionally, all keys in *bindings* must be symbols. Values in the association list will be evaluated before being bound, and this is done sequentially, as in the behaviour of Common Lisp `let*` rather than of Common Lisp `let`.
-
-#### (list *o*...)
-
-Returns a list of the values of all of its arguments in sequence.
-
-#### (mapcar *f* *s*)
-
-Applies the function *f* to each element of the sequence *s*, and returns a new sequence of the results.
-
-#### (meta *o*), (metadata *o*)
-
-Returns metadata on *o*.
-
-#### (multiply *n1* *n2* ...), (\* *n1* *n2* ...)
-
-Returns the product of multiplying together all of its numeric arguments.
-
-#### (negative? n1)
-
-Returns `t` if its argument is a negative number, else `nil`.
-
-#### (oblist)
-
-Returns a sequence of all the names bound in the root of the naming system.
-
-#### (open *url* *read?*)
-
-Opens a stream to the specified *url*. If a second argument is present and is non-`nil`, the stream is opened for reading; otherwise, it's opened for writing.
-
-#### (print *o* [*stream*])
-
-Prints the print-name of object *o* to the output stream which is the value of *stream*, or to the value of \*out\* in the current environment if no *stream* is provided.
-
-#### (put! *map* *key* *value*)
-
-Puts *value* as the value of *key* in hashmap *map*, destructively modifying it, and returns the map. Note that in future this will work only if the current user has write access to the specified map.
-
-#### (put-all! *map* *assoc*)
-
-Puts each (+key* . *value*) pair from the association list *assoc* into this *map*, destructively modifying it, and returns the map. Note that in future this will work only if the current user has write access to the specified map.
-
-#### (read [*stream*])
-
-Reads a single Lisp form from the input stream which is the value of *stream*, or from the value of \*in\* in the current environment if no *stream* is provided.
-
-#### (read-char [*stream*])
-
-Return the next character from the stream indicated by *stream*, or from the value of \*in\* in the current environment if no *stream* is provided; further arguments are ignored.
-
-#### (repl [*prompt* *input* *output*))
-
-Initiate a new Read/Eval/Print loop with this *prompt*, reading from this *input* stream and writing to this *output* stream. All arguments are optional and default sensibly if omitted. TODO: doesn't actually work yet.
-
-#### (reverse *seq*)
-
-Return a new sequence of the same type as *seq*, containing the same elements but in the reverse order.
-
-#### (slurp *in*)
-
-Reads all available characters on input stream *in* into a string, and returns the string.
-
-#### (source *fn*)
-
-Should return the source code of the function or special form *fn*, but as we don't yet
-have a compiler, doesn't.
-
-#### (subtract *n1* *n2*), (- *n1* *n2*)
-
-Subtracts the numeric value *n2* from the numeric value *n1*, and returns the difference.
-
-#### (throw *message*)
-
-Throws an exception, with the payload *message*. While *message* is at present most usefully a string, it doesn't have to be. Returns the exception, but as exceptions are handled specially by `eval`, it is returned to the catch block of the nearest `try` expression on the stack.
-
-#### (time [*milliseconds-since-epoch*])
-
-Returns a time object whose value is the specified number of *milliseconds-since-epoch*, where the Post Scarcity Software Environment epoch is 14 billion years prior to the UN*X epoch. If *milliseconds-since-epoch* is not specified, returns a time object representing the UTC time when the function was executed.
-
-#### (type *o*)
-
-Returns a string representing the type -- actually the tag value -- of the object *o*.
-
-### Special forms
-
-#### (cond (test value) ...)
-
-Evaluates a series of *(test value)* clauses in turn until a test returns non-nil, when the corresponding value is returned and further tests are not evaluated. This is the same syntax as Common Lisp's `cond` implementation, and different from Clojure's.
-
-It's conventional in Lisp to have a final clause in a `cond` block with the test `t`; however, since we have keywords which are always truthy, it would be equally valid to use `:else` or `:default` as final fallback tests.
-
-#### (lambda (arg ...) form ...), (λ (arg ...) form ...)
-
-Returns an anonymous fuction which evaluates each of the *form*s sequentially in an environment in which the specified *arg*s are bound, and returns the value of the last such form.
-
-#### (let ((*var* . *val*) ...) form ...)
-
-Evaluates each of these *form*s sequentially in an environment in which each *var* is bound to the respective *val* in the bindings specified, and returns the value of the last form.
-
-#### (nlambda (arg ...) form ...), (nλ (arg ...) form ...)
-
-Returns an anonymous special form which evaluates each of the *form*s sequentially in an environment in which the specified *arg*s are bound, and returns the value of the last such form.
-
-#### (progn *f* ...)
-
-Evaluates each of the forms which are its arguments in turn and returns the value of the last.
-
-#### (quote *o*), '*o*
-
-Returns *o*, unevaluated.
-
-#### (set! *name* *value* [*namespace*])
-
-Sets (destructively modifies) the value of *name* this *value* in the root namespace. The *namespace* argument is currently ignored but in future is anticipated to be a path specification of a namespace to be modified.
-
-#### (try (*form* ...) (*handler* ...))
-
-Attempt to evaluate, sequentially, each of the *form*s in the first sequence, and return the value of the last of them; however, if any of them cause an exception to be thrown, then evaluate sequentially each of the *handler*s in the second sequence.
-
-It is recommended that you structure this as follows:
-
-`lisp
- (try
- (:body
- (print "hello")
- (/ 1 'a)
- (print "goodbye"))
- (:catch
- (print "Well, that failed.")
- 5))
-`
-
-Here, `:body` and `:catch` are syntactic sugar which will not affect the final value.
-
-### Type values
-
-The following types are known. Further types can be defined, and ultimately it should be possible to define further types in Lisp, but these are what you have to be going on with. Note that where this documentation differs from `memory/consspaceobject.h`, this documentation is *wrong*.
-
-#### CONS
-
-An ordinary cons cell: that is to say, a pair.
-
-#### EXEP
-
-An exception
-
-#### FREE
-
-An unallocated memory cell. User programs should never see this.
-
-#### FUNC
-
-A primitive or compiled Lisp function \-- one whose arguments are pre-evaluated.
-
-#### HASH
-
-A hash map (in vector space)
-
-#### INTR
-
-An arbitrarily large integer number.
-
-#### KEYW
-
-A keyword - an interned, self-evaluating string.
-
-#### LMBA
-
-A lambda cell. Lambdas are the interpretable (source) versions of functions.
-
-#### LOOP
-
-Internal to the workings of the ••loop** function. User functions should never see this.
-
-#### NIL
-
-The special cons cell at address {0,0} whose **car** and **cdr** both point to itself. The canonical empty set. Generally, treated as being indicative of falsity.
-
-#### NLMD
-
-An nlambda cell. NLambdas are the interpretable (source) versions of special forms.
-
-#### RTIO
-
-A rational number, stored as pointers two integers representing dividend and divisor respectively.
-
-#### READ
-
-An open read stream.
-
-#### REAL
-
-A real number, represented internally as an IEEE 754-2008 `binary64`.
-
-#### SPFM
-
-A compiled or primitive special form - one whose arguments are not pre-evaluated but passed as provided.
-
-#### STAK
-
-A stack frame. In vector space.
-
-#### STRG
-
-A string of [UTF-32](https://en.wikipedia.org/wiki/UTF-32) characters, stored as a linked list. Self evaluating.
-
-#### SYMB
-
-A symbol is just like a string except not self-evaluating. Later, there may be some restrictions on what characters are legal in a symbol, but at present there are not.
-
-#### TIME
-
-A time stamp. The epoch for the Post Scarcity Software Environment is 14 billion years before the UN*X epoch, and is chosen as being a reasonable estimate for the birth of the universe, and thus of the start of time.
-
-#### TRUE
-
-The special cell at address {0,1} which is canonically different from NIL.
-
-#### VECP
-
-A pointer to an object in vector space. User functions shouldn't see this, they should see the type of the vector-space object indicated.
-
-#### VECT
-
-A vector of objects. In vector space.
-
-#### WRIT
-
-An open write stream.
-
-
-
## License
Copyright © 2017 [Simon Brooke](mailto:simon@journeyman.cc)
diff --git a/docs/How-do-we-notate-paths.md b/docs/How-do-we-notate-paths.md
deleted file mode 100644
index 7cdbcb0..0000000
--- a/docs/How-do-we-notate-paths.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# How do we notate paths?
-
-In order to make the namespaces thing work, we need a convenient way to notate paths from the current namespace to a target, or from the root to a target. This is similar to relative and absolute paths in UNIX, except that in PSSE there is no concept of a single or privileged ancestor namespace to the current namespace, so you have no equivalent of `../`.
-
-In this discussion, a **namespace** is just a named, mutable hashmap (but not necessarily mutable by all users; indeed namespaces will almost always be mutable only by selected users. I cannot presently see a justified use for a publicly writable namespace). '**Named**', of a hashmap, merely means there is some path from the privileged root namespace which is the value of `oblist` which leads to that hashmap. A **path** is in principle just a sequence of keys, such that the value of each successive key is bound to a namespace in the namespace bound by its predecessor. The evaluable implementation of paths will be discussed later.
-
-I think also that there must be a privileged **session** namespace, containing information about the current session, which the user can read but not write.
-
-## Security considerations
-
-What's important is that a user cannot rebind privileged names in their own environment. Thus to ensure privileged names, such names must be paths either from the `oblist`or from the current session. So we need magic, privileged notations for these things built into the reader, which cannot be overridden.
-
-This kind of takes away from my general feeling that users should be able to override *anything*. but hey, that's engineering for you.
-
-Users should be able to override reader macros generally; a programmable reader is in the medium term something which should be implemented. But the privileged syntax for paths should not be overridable.
-
-## Current state of the reader
-
-At present, you can rebind the value of the symbol `oblist` in the runtime environment. In principle, you should be able to rebind any symbol. Paths and symbols are not the same.
-
-At present, the colon character is a separator character. So if you type
-
-> (list :foo:bar:ban)
-
-the reader will return
-
-> (list :foo :bar :ban)
-
-That's significant, and helpful.
-
-## Constructing path notation
-
-The Clojure threading macro, `->`, is a useful example of how we can implement this. Essentially it takes a expression as its first argument, passes the value of that expression to the function which is its second argument, the value of that as argument to the function which is its next, and so on. Given that, in Clojure, an expression which has a keyword in the function position and a hashmap in the argument position will return the value of that keyword in that hashmap, this means that, given the hashmap
-
-> (def x {:foo {:bar {:ban "Howzat!!"}}})
-
-the expression
-
-> (-> x :foo :bar :ban)
-
-will return
-
-> "Howzat!!"
-
-So, in general, if we implement the 'keyword in the function position' `eval` hack and the threading macro, then something like
-
-> (-> oblist :users :simon :functions 'foo)
-
-should return the value of the symbol `foo` in the `:functions` of the user called `:simon`.
-
-That's stage one of our goal.
-
-Stage two of our goal is that a stream of non-separator characters separated by colons should be interpreted as a list of keywords. Thus typing
-
-> :foo:bar:ban
-
-should result in not just `:foo`being read, but the list `(:foo :bar :ban)`(? not sure about this)
-
-Stage 3 is to allow a symbol to be appended to a sequence of keywords written by using `/`as a separator, so
-
-> :foo:bar/ban
-
-would be read as `(:foo :bar 'ban)`
-
-Finally, we need privileged notation for root (oblist) and for session. There are very few non-alpha-numeric characters which are available on a standard keyboard and which are not already used as significant lexical characters in Lisp readers. PSSE is not limited, of course, to the characters which are part of the ASCII character set, but it is helpful to use symbols which are reasonably convenient to type, possibly with special keyboard bindings.
-
-So I'm going to propose that the reader should interpret
-
-> /:users:simon:functions/assoc
-
-as
-
-> (-> oblist :users :simon :functions 'assoc)
-
-where `oblist` is the actual privileged global object list, not just the current binding of `oblist` in the environment. Thus, this expression would return my personal version of the function `assoc`, whatever the symbol `assoc` was bound to in the runtime environment.
-
-The use of the leading slash here follows UNIX convention.
-
-I'm going to suggest that the session is referenced by the character §, otherwise known as the 'silcrow'. This is not available on most keyboard mappings, so a custom mapping might be needed, or we might have to fall back on `$`.
-
-Thus the reader should interpret
-
-> §:user
-
-as
-
-> (-> session :user)
-
-where `session`is again a system privileged value, not the binding of `session` in the current environment.
\ No newline at end of file
diff --git a/docs/Hybrid-assoc-lists.md b/docs/Hybrid-assoc-lists.md
deleted file mode 100644
index 5bb6ca8..0000000
--- a/docs/Hybrid-assoc-lists.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Hybrid assoc lists
-
-In it's current very prototype stage, PSSE has to forms of name/value store. One is the assoc list, the other is the hashmap.
-
-An assoc (association) list is a list of the form:
-
- ((name1 . value1)(name2 . value2)(name3 . value3)...)
-
-Hashmaps have many very clear advantages, but assoc lists have one which is very important in the evaluation environment, and that is precisely its sequentiality. Thus, if the same name is bound twice on an assoc list, the value nearest the head is the one which will be recovered:
-
- (assoc :bar '((:foo . 1) (:bar . "Hello there!")(:ban . 3)(:bar . 2)))
- => "Hello there!"
-
-Why does this matter? Well, for precisely the same reason it matters when a UNIX system searches for an executable.
-
-Suppose Clare is a user who trusts both Alice and Bob, but she trusts Alice more than Bob. Suppose both Alice and Bob have written implementations of a function called `froboz`. Suppose Clare invokes
-
- (froboz 3)
-
-Which implementation of `froboz` should be evaluated? An assoc list makes that simple. If Clare binds Alice's implementation into her environment later than Bob's, Alice's will be the one found.
-
-But an assoc list is also fearsomely inefficient, especially if we are in a system with many thousands of names, each of which may be bound multiple times in typical runtime environment.
-
-How to resolve this? How to get some of the benefits of sequential access of assoc lists, with some of the efficiency benefits of hashmaps? What I'm going to propose is a **hybrid assoc list**, that is to say, a list whose members are either
-
-1. (key . value) pairs, or else
-2. hashmaps.
-
-So suppose we have a list, `l`, thus:
-
- ((:foo . 1) (:bar . 2) {:foo "not this" :ban 3} (:ban . "not this either") (:froboz . 4))
-
-Then:
-
- (assoc :foo l) => 1
- (assoc :bar l) => 2
- (assoc :ban l) => 3
- (assoc :froboz l) => 4
-
-This will make the implementation of namespaces and search paths vastly easier.
\ No newline at end of file
diff --git a/lisp/defun.lisp b/lisp/defun.lisp
index a6d80f5..cec893b 100644
--- a/lisp/defun.lisp
+++ b/lisp/defun.lisp
@@ -9,11 +9,6 @@
(set (car form) (apply 'lambda (cdr form))))
(t nil))))
-(set! defun!
- (nlambda
- form
- (eval (list 'set! (car form) (cons 'lambda (cdr form))))))
-
(defun! square (x) (* x x))
(set! defsp!
diff --git a/src/arith/integer.c b/src/arith/integer.c
index eef171b..1b2667c 100644
--- a/src/arith/integer.c
+++ b/src/arith/integer.c
@@ -18,12 +18,12 @@
#include
#include
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
+#include "conspage.h"
+#include "consspaceobject.h"
#include "debug.h"
-#include "ops/equal.h"
-#include "ops/lispops.h"
-#include "arith/peano.h"
+#include "equal.h"
+#include "lispops.h"
+#include "peano.h"
/**
* hexadecimal digits for printing numbers.
@@ -46,10 +46,11 @@ struct cons_pointer make_integer( int64_t value, struct cons_pointer more ) {
debug_print( L"Entering make_integer\n", DEBUG_ALLOC );
if ( integerp( more ) || nilp( more ) ) {
- result = allocate_cell( INTEGERTV );
+ result = allocate_cell( INTEGERTAG );
struct cons_space_object *cell = &pointer2cell( result );
cell->payload.integer.value = value;
cell->payload.integer.more = more;
+
}
debug_print( L"make_integer: returning\n", DEBUG_ALLOC );
@@ -76,7 +77,7 @@ __int128_t cell_value( struct cons_pointer c, char op, bool is_first_cell ) {
__int128_t result = ( __int128_t ) integerp( c ) ?
( val == 0 ) ? carry : val : op == '*' ? 1 : 0;
debug_printf( DEBUG_ARITH,
- L"cell_value: raw value is %ld, is_first_cell = %s; '%4.4s'; returning ",
+ L"cell_value: raw value is %ld, is_first_cell = %s; %4.4s; returning ",
val, is_first_cell ? "true" : "false",
pointer2cell( c ).tag.bytes );
debug_print_128bit( result, DEBUG_ARITH );
@@ -218,19 +219,18 @@ struct cons_pointer base_partial( int depth ) {
/**
* destructively modify this `partial` by appending this `digit`.
*/
-struct cons_pointer append_digit( struct cons_pointer partial,
- struct cons_pointer digit ) {
+struct cons_pointer append_digit( struct cons_pointer partial, struct cons_pointer digit) {
struct cons_pointer c = partial;
struct cons_pointer result = partial;
- if ( nilp( partial ) ) {
+ if (nilp( partial)) {
result = digit;
} else {
- while ( !nilp( pointer2cell( c ).payload.integer.more ) ) {
- c = pointer2cell( c ).payload.integer.more;
+ while ( !nilp( pointer2cell(c).payload.integer.more)) {
+ c = pointer2cell(c).payload.integer.more;
}
- ( &pointer2cell( c ) )->payload.integer.more = digit;
+ (&pointer2cell(c))->payload.integer.more = digit;
}
return result;
}
@@ -249,8 +249,8 @@ struct cons_pointer append_digit( struct cons_pointer partial,
* @param b an integer.
*/
struct cons_pointer multiply_integers( struct cons_pointer a,
- struct cons_pointer b ) {
- struct cons_pointer result = make_integer( 0, NIL );
+ struct cons_pointer b ) {
+ struct cons_pointer result = make_integer( 0, NIL);
bool neg = is_negative( a ) != is_negative( b );
bool is_first_b = true;
int i = 0;
@@ -265,7 +265,7 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
/* for each digit in a, starting with the least significant (ai) */
for ( struct cons_pointer ai = a; !nilp( ai );
- ai = pointer2cell( ai ).payload.integer.more ) {
+ ai = pointer2cell(ai).payload.integer.more) {
/* set carry to 0 */
__int128_t carry = 0;
@@ -275,41 +275,41 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
/* for each digit in b, starting with the least significant (bj) */
for ( struct cons_pointer bj = b; !nilp( bj );
- bj = pointer2cell( bj ).payload.integer.more ) {
+ bj = pointer2cell(bj).payload.integer.more) {
debug_printf( DEBUG_ARITH,
- L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n",
- pointer2cell( ai ).payload.integer.value,
- pointer2cell( bj ).payload.integer.value, i );
+ L"multiply_integers: a[i] = %Ld, b[j] = %Ld, i = %d\n",
+ pointer2cell(ai).payload.integer.value,
+ pointer2cell(bj).payload.integer.value, i);
/* multiply ai with bj and add the carry, resulting in a
* value xj which may exceed one digit */
- __int128_t xj = pointer2cell( ai ).payload.integer.value *
- pointer2cell( bj ).payload.integer.value;
+ __int128_t xj = pointer2cell(ai).payload.integer.value *
+ pointer2cell(bj).payload.integer.value;
xj += carry;
/* if xj exceeds one digit, break it into the digit dj and
* the carry */
carry = xj >> 60;
- struct cons_pointer dj = make_integer( xj & MAX_INTEGER, NIL );
+ struct cons_pointer dj = make_integer( xj & MAX_INTEGER, NIL);
/* destructively modify ri by appending dj */
- ri = append_digit( ri, dj );
- } /* end for bj */
+ ri = append_digit( ri, dj);
+ } /* end for bj */
/* if carry is not equal to zero, append it as a final digit
* to ri */
- if ( carry != 0 ) {
- ri = append_digit( ri, make_integer( carry, NIL ) );
+ if (carry != 0) {
+ ri = append_digit( ri, make_integer( carry, NIL));
}
/* add ri to result */
- result = add_integers( result, ri );
+ result = add_integers( result, ri);
debug_print( L"multiply_integers: result is ", DEBUG_ARITH );
debug_print_object( result, DEBUG_ARITH );
debug_println( DEBUG_ARITH );
- } /* end for ai */
+ } /* end for ai */
}
debug_print( L"multiply_integers returning: ", DEBUG_ARITH );
@@ -343,16 +343,13 @@ struct cons_pointer integer_to_string_add_digit( int digit, int digits,
* to be looking to the next. H'mmmm.
*/
struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
- int base ) {
+ int base ) {
struct cons_pointer result = NIL;
if ( integerp( int_pointer ) ) {
- struct cons_pointer next =
- pointer2cell( int_pointer ).payload.integer.more;
- __int128_t accumulator =
- llabs( pointer2cell( int_pointer ).payload.integer.value );
- bool is_negative =
- pointer2cell( int_pointer ).payload.integer.value < 0;
+ struct cons_pointer next = pointer2cell( int_pointer ).payload.integer.more;
+ __int128_t accumulator = llabs( pointer2cell( int_pointer ).payload.integer.value );
+ bool is_negative = pointer2cell( int_pointer ).payload.integer.value < 0;
int digits = 0;
if ( accumulator == 0 && nilp( next ) ) {
@@ -360,14 +357,13 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
} else {
while ( accumulator > 0 || !nilp( next ) ) {
if ( accumulator < MAX_INTEGER && !nilp( next ) ) {
- accumulator +=
- ( pointer2cell( next ).payload.integer.value << 60 );
- next = pointer2cell( next ).payload.integer.more;
+ accumulator += (pointer2cell(next).payload.integer.value << 60);
+ next = pointer2cell(next).payload.integer.more;
}
int offset = ( int ) ( accumulator % base );
debug_printf( DEBUG_IO,
- L"integer_to_string: digit is %ld, hexadecimal is %c, accumulator is: ",
- offset, hex_digits[offset] );
+ L"integer_to_string: digit is %ld, hexadecimal is %c, accumulator is: ",
+ offset, hex_digits[offset] );
debug_print_128bit( accumulator, DEBUG_IO );
debug_print( L"; result is: ", DEBUG_IO );
debug_print_object( result, DEBUG_IO );
@@ -379,7 +375,7 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
}
if ( stringp( result )
- && pointer2cell( result ).payload.string.character == L',' ) {
+ && pointer2cell( result ).payload.string.character == L',' ) {
/* if the number of digits in the string is divisible by 3, there will be
* an unwanted comma on the front. */
result = pointer2cell( result ).payload.string.cdr;
@@ -394,38 +390,3 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
return result;
}
-
-/**
- * true if a and be are both integers whose value is the same value.
- */
-bool equal_integer_integer( struct cons_pointer a, struct cons_pointer b ) {
- bool result = false;
-
- if ( integerp( a ) && integerp( b ) ) {
- struct cons_space_object *cell_a = &pointer2cell( a );
- struct cons_space_object *cell_b = &pointer2cell( b );
-
- result =
- cell_a->payload.integer.value == cell_b->payload.integer.value;
- }
-
- return result;
-}
-
-/**
- * true if `a` is an integer, and `b` is a real number whose value is the
- * value of that integer.
- */
-bool equal_integer_real( struct cons_pointer a, struct cons_pointer b ) {
- bool result = false;
-
- if ( integerp( a ) && realp( b ) ) {
- long double bv = pointer2cell( b ).payload.real.value;
-
- if ( floor( bv ) == bv ) {
- result = pointer2cell( a ).payload.integer.value == ( int64_t ) bv;
- }
- }
-
- return result;
-}
diff --git a/src/arith/integer.h b/src/arith/integer.h
index 09a7a83..117a0bf 100644
--- a/src/arith/integer.h
+++ b/src/arith/integer.h
@@ -11,9 +11,6 @@
#ifndef __integer_h
#define __integer_h
-#include
-#include
-
struct cons_pointer make_integer( int64_t value, struct cons_pointer more );
struct cons_pointer add_integers( struct cons_pointer a,
@@ -25,8 +22,4 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
int base );
-bool equal_integer_integer( struct cons_pointer a, struct cons_pointer b );
-
-bool equal_integer_real( struct cons_pointer a, struct cons_pointer b );
-
#endif
diff --git a/src/arith/peano.c b/src/arith/peano.c
index ae23a00..8e4cb43 100644
--- a/src/arith/peano.c
+++ b/src/arith/peano.c
@@ -14,19 +14,19 @@
#include
#include
-#include "memory/consspaceobject.h"
-#include "memory/conspage.h"
+#include "consspaceobject.h"
+#include "conspage.h"
#include "debug.h"
-#include "ops/equal.h"
-#include "arith/integer.h"
-#include "ops/intern.h"
-#include "ops/lispops.h"
-#include "arith/peano.h"
-#include "io/print.h"
-#include "arith/ratio.h"
-#include "io/read.h"
-#include "arith/real.h"
-#include "memory/stack.h"
+#include "equal.h"
+#include "integer.h"
+#include "intern.h"
+#include "lispops.h"
+#include "peano.h"
+#include "print.h"
+#include "ratio.h"
+#include "read.h"
+#include "real.h"
+#include "stack.h"
long double to_long_double( struct cons_pointer arg );
int64_t to_long_int( struct cons_pointer arg );
@@ -86,7 +86,8 @@ bool is_negative( struct cons_pointer arg ) {
return result;
}
-struct cons_pointer absolute( struct cons_pointer arg ) {
+struct cons_pointer absolute( struct cons_pointer frame_pointer,
+ struct cons_pointer arg ) {
struct cons_pointer result = NIL;
struct cons_space_object cell = pointer2cell( arg );
@@ -98,7 +99,9 @@ struct cons_pointer absolute( struct cons_pointer arg ) {
cell.payload.integer.more );
break;
case RATIOTV:
- result = make_ratio( absolute( cell.payload.ratio.dividend ),
+ result = make_ratio( frame_pointer,
+ absolute( frame_pointer,
+ cell.payload.ratio.dividend ),
cell.payload.ratio.divisor );
break;
case REALTV:
@@ -207,7 +210,7 @@ int64_t to_long_int( struct cons_pointer arg ) {
struct cons_pointer lisp_absolute( struct stack_frame
*frame, struct cons_pointer frame_pointer, struct
cons_pointer env ) {
- return absolute( frame->arg[0] );
+ return absolute( frame_pointer, frame->arg[0] );
}
/**
@@ -247,7 +250,8 @@ struct cons_pointer add_2( struct stack_frame *frame,
result = add_integers( arg1, arg2 );
break;
case RATIOTV:
- result = add_integer_ratio( arg1, arg2 );
+ result =
+ add_integer_ratio( frame_pointer, arg1, arg2 );
break;
case REALTV:
result =
@@ -267,10 +271,11 @@ struct cons_pointer add_2( struct stack_frame *frame,
result = arg2;
break;
case INTEGERTV:
- result = add_integer_ratio( arg2, arg1 );
+ result =
+ add_integer_ratio( frame_pointer, arg2, arg1 );
break;
case RATIOTV:
- result = add_ratio_ratio( arg1, arg2 );
+ result = add_ratio_ratio( frame_pointer, arg1, arg2 );
break;
case REALTV:
result =
@@ -378,7 +383,9 @@ struct cons_pointer multiply_2( struct stack_frame *frame,
result = multiply_integers( arg1, arg2 );
break;
case RATIOTV:
- result = multiply_integer_ratio( arg1, arg2 );
+ result =
+ multiply_integer_ratio( frame_pointer, arg1,
+ arg2 );
break;
case REALTV:
result =
@@ -401,10 +408,13 @@ struct cons_pointer multiply_2( struct stack_frame *frame,
result = arg2;
break;
case INTEGERTV:
- result = multiply_integer_ratio( arg2, arg1 );
+ result =
+ multiply_integer_ratio( frame_pointer, arg2,
+ arg1 );
break;
case RATIOTV:
- result = multiply_ratio_ratio( arg1, arg2 );
+ result =
+ multiply_ratio_ratio( frame_pointer, arg1, arg2 );
break;
case REALTV:
result =
@@ -486,7 +496,8 @@ struct cons_pointer lisp_multiply( struct
* return a cons_pointer indicating a number which is the
* 0 - the number indicated by `arg`.
*/
-struct cons_pointer negative( struct cons_pointer arg ) {
+struct cons_pointer negative( struct cons_pointer frame,
+ struct cons_pointer arg ) {
struct cons_pointer result = NIL;
struct cons_space_object cell = pointer2cell( arg );
@@ -503,7 +514,9 @@ struct cons_pointer negative( struct cons_pointer arg ) {
result = TRUE;
break;
case RATIOTV:
- result = make_ratio( negative( cell.payload.ratio.dividend ),
+ result = make_ratio( frame,
+ negative( frame,
+ cell.payload.ratio.dividend ),
cell.payload.ratio.divisor );
break;
case REALTV:
@@ -557,18 +570,20 @@ struct cons_pointer subtract_2( struct stack_frame *frame,
result = arg2;
break;
case INTEGERTV:{
- struct cons_pointer i = negative( arg2 );
+ struct cons_pointer i =
+ negative( frame_pointer, arg2 );
inc_ref( i );
result = add_integers( arg1, i );
dec_ref( i );
}
break;
case RATIOTV:{
- struct cons_pointer tmp = make_ratio( arg1,
- make_integer( 1,
- NIL ) );
+ struct cons_pointer tmp =
+ make_ratio( frame_pointer, arg1,
+ make_integer( 1, NIL ) );
inc_ref( tmp );
- result = subtract_ratio_ratio( tmp, arg2 );
+ result =
+ subtract_ratio_ratio( frame_pointer, tmp, arg2 );
dec_ref( tmp );
}
break;
@@ -590,16 +605,17 @@ struct cons_pointer subtract_2( struct stack_frame *frame,
result = arg2;
break;
case INTEGERTV:{
- struct cons_pointer tmp = make_ratio( arg2,
- make_integer( 1,
- NIL ) );
+ struct cons_pointer tmp =
+ make_ratio( frame_pointer, arg2,
+ make_integer( 1, NIL ) );
inc_ref( tmp );
- result = subtract_ratio_ratio( arg1, tmp );
+ result =
+ subtract_ratio_ratio( frame_pointer, arg1, tmp );
dec_ref( tmp );
}
break;
case RATIOTV:
- result = subtract_ratio_ratio( arg1, arg2 );
+ result = subtract_ratio_ratio( frame_pointer, arg1, arg2 );
break;
case REALTV:
result =
@@ -671,11 +687,11 @@ struct cons_pointer lisp_divide( struct
break;
case INTEGERTV:{
struct cons_pointer unsimplified =
- make_ratio( frame->arg[0],
+ make_ratio( frame_pointer, frame->arg[0],
frame->arg[1] );
/* OK, if result may be unsimplified, we should not inc_ref it
* - but if not, we should dec_ref it. */
- result = simplify_ratio( unsimplified );
+ result = simplify_ratio( frame_pointer, unsimplified );
if ( !eq( unsimplified, result ) ) {
dec_ref( unsimplified );
}
@@ -684,9 +700,11 @@ struct cons_pointer lisp_divide( struct
case RATIOTV:{
struct cons_pointer one = make_integer( 1, NIL );
struct cons_pointer ratio =
- make_ratio( frame->arg[0], one );
+ make_ratio( frame_pointer, frame->arg[0], one );
inc_ref( ratio );
- result = divide_ratio_ratio( ratio, frame->arg[1] );
+ result =
+ divide_ratio_ratio( frame_pointer, ratio,
+ frame->arg[1] );
dec_ref( ratio );
}
break;
@@ -711,16 +729,19 @@ struct cons_pointer lisp_divide( struct
struct cons_pointer one = make_integer( 1, NIL );
inc_ref( one );
struct cons_pointer ratio =
- make_ratio( frame->arg[1], one );
+ make_ratio( frame_pointer, frame->arg[1], one );
inc_ref( ratio );
- result = divide_ratio_ratio( frame->arg[0], ratio );
+ result =
+ divide_ratio_ratio( frame_pointer, frame->arg[0],
+ ratio );
dec_ref( ratio );
dec_ref( one );
}
break;
case RATIOTV:
result =
- divide_ratio_ratio( frame->arg[0], frame->arg[1] );
+ divide_ratio_ratio( frame_pointer, frame->arg[0],
+ frame->arg[1] );
break;
case REALTV:
result =
diff --git a/src/arith/peano.h b/src/arith/peano.h
index 3076391..7ad7662 100644
--- a/src/arith/peano.h
+++ b/src/arith/peano.h
@@ -19,16 +19,16 @@
bool zerop( struct cons_pointer arg );
-struct cons_pointer negative( struct cons_pointer arg );
+struct cons_pointer negative( struct cons_pointer frame,
+ struct cons_pointer arg );
bool is_negative( struct cons_pointer arg );
-struct cons_pointer absolute( struct cons_pointer arg );
+struct cons_pointer absolute( struct cons_pointer frame_pointer,
+ struct cons_pointer arg );
long double to_long_double( struct cons_pointer arg );
-int64_t to_long_int( struct cons_pointer arg );
-
struct cons_pointer lisp_absolute( struct stack_frame
*frame, struct cons_pointer frame_pointer, struct
cons_pointer env );
@@ -46,7 +46,8 @@ struct cons_pointer
lisp_multiply( struct stack_frame *frame,
struct cons_pointer frame_pointer, struct cons_pointer env );
-struct cons_pointer negative( struct cons_pointer arg );
+struct cons_pointer negative( struct cons_pointer frame,
+ struct cons_pointer arg );
struct cons_pointer subtract_2( struct stack_frame *frame,
struct cons_pointer frame_pointer,
diff --git a/src/arith/ratio.c b/src/arith/ratio.c
index 5135d6b..65b09da 100644
--- a/src/arith/ratio.c
+++ b/src/arith/ratio.c
@@ -11,15 +11,15 @@
#include
#include
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
+#include "conspage.h"
+#include "consspaceobject.h"
#include "debug.h"
-#include "ops/equal.h"
-#include "arith/integer.h"
-#include "ops/lispops.h"
-#include "arith/peano.h"
-#include "io/print.h"
-#include "arith/ratio.h"
+#include "equal.h"
+#include "integer.h"
+#include "lispops.h"
+#include "peano.h"
+#include "print.h"
+#include "ratio.h"
/**
@@ -43,46 +43,52 @@ int64_t least_common_multiple( int64_t m, int64_t n ) {
return m / greatest_common_divisor( m, n ) * n;
}
-struct cons_pointer simplify_ratio( struct cons_pointer pointer ) {
- struct cons_pointer result = pointer;
- struct cons_space_object cell = pointer2cell( pointer );
- struct cons_space_object dividend =
- pointer2cell( cell.payload.ratio.dividend );
- struct cons_space_object divisor =
- pointer2cell( cell.payload.ratio.divisor );
+/**
+ * return a cons_pointer indicating a number which is of the
+ * same value as the ratio indicated by `arg`, but which may
+ * be in a simplified representation.
+ * @exception If `arg` isn't a ratio, will return an exception.
+ */
+struct cons_pointer simplify_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg ) {
+ struct cons_pointer result = arg;
- if ( divisor.payload.integer.value == 1 ) {
- result = pointer2cell( pointer ).payload.ratio.dividend;
- } else {
- if ( ratiop( pointer ) ) {
- int64_t ddrv = dividend.payload.integer.value,
- drrv = divisor.payload.integer.value,
- gcd = greatest_common_divisor( ddrv, drrv );
+ if ( ratiop( arg ) ) {
+ int64_t ddrv =
+ pointer2cell( pointer2cell( arg ).payload.ratio.dividend ).
+ payload.integer.value, drrv =
+ pointer2cell( pointer2cell( arg ).payload.ratio.divisor ).
+ payload.integer.value, gcd = greatest_common_divisor( ddrv, drrv );
- if ( gcd > 1 ) {
- if ( drrv / gcd == 1 ) {
- result = make_integer( ddrv / gcd, NIL );
- } else {
- result =
- make_ratio( make_integer( ddrv / gcd, NIL ),
- make_integer( drrv / gcd, NIL ) );
- }
+ if ( gcd > 1 ) {
+ if ( drrv / gcd == 1 ) {
+ result = make_integer( ddrv / gcd, NIL );
+ } else {
+ result =
+ make_ratio( frame_pointer, make_integer( ddrv / gcd, NIL ),
+ make_integer( drrv / gcd, NIL ) );
}
}
+ } else {
+ result =
+ throw_exception( make_cons( c_string_to_lisp_string
+ ( L"Shouldn't happen: bad arg to simplify_ratio" ),
+ arg ), frame_pointer );
}
return result;
-
}
+
/**
* return a cons_pointer indicating a number which is the sum of
* the ratios indicated by `arg1` and `arg2`.
* @exception will return an exception if either `arg1` or `arg2` is not a
* rational number.
*/
-struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
+struct cons_pointer add_ratio_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg1,
struct cons_pointer arg2 ) {
struct cons_pointer r, result;
@@ -110,17 +116,18 @@ struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
m1, m2 );
if ( dr1v == dr2v ) {
- r = make_ratio( make_integer( dd1v + dd2v, NIL ),
+ r = make_ratio( frame_pointer,
+ make_integer( dd1v + dd2v, NIL ),
cell1.payload.ratio.divisor );
} else {
struct cons_pointer dd1vm = make_integer( dd1v * m1, NIL ),
dr1vm = make_integer( dr1v * m1, NIL ),
dd2vm = make_integer( dd2v * m2, NIL ),
dr2vm = make_integer( dr2v * m2, NIL ),
- r1 = make_ratio( dd1vm, dr1vm ),
- r2 = make_ratio( dd2vm, dr2vm );
+ r1 = make_ratio( frame_pointer, dd1vm, dr1vm ),
+ r2 = make_ratio( frame_pointer, dd2vm, dr2vm );
- r = add_ratio_ratio( r1, r2 );
+ r = add_ratio_ratio( frame_pointer, r1, r2 );
/* because the references on dd1vm, dr1vm, dd2vm and dr2vm were
* never incremented except when making r1 and r2, decrementing
@@ -129,7 +136,7 @@ struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
dec_ref( r2 );
}
- result = simplify_ratio( r );
+ result = simplify_ratio( frame_pointer, r );
if ( !eq( r, result ) ) {
dec_ref( r );
}
@@ -139,7 +146,7 @@ struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
( L"Shouldn't happen: bad arg to add_ratio_ratio" ),
make_cons( arg1,
make_cons( arg2, NIL ) ) ),
- NIL );
+ frame_pointer );
}
debug_print( L" => ", DEBUG_ARITH );
@@ -156,16 +163,16 @@ struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
* `ratarg`.
* @exception if either `intarg` or `ratarg` is not of the expected type.
*/
-struct cons_pointer add_integer_ratio( struct cons_pointer intarg,
+struct cons_pointer add_integer_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer intarg,
struct cons_pointer ratarg ) {
struct cons_pointer result;
if ( integerp( intarg ) && ratiop( ratarg ) ) {
- // TODO: not longer works
struct cons_pointer one = make_integer( 1, NIL ),
- ratio = make_ratio( intarg, one );
+ ratio = make_ratio( frame_pointer, intarg, one );
- result = add_ratio_ratio( ratio, ratarg );
+ result = add_ratio_ratio( frame_pointer, ratio, ratarg );
dec_ref( one );
dec_ref( ratio );
@@ -175,7 +182,8 @@ struct cons_pointer add_integer_ratio( struct cons_pointer intarg,
( L"Shouldn't happen: bad arg to add_integer_ratio" ),
make_cons( intarg,
make_cons( ratarg,
- NIL ) ) ), NIL );
+ NIL ) ) ),
+ frame_pointer );
}
return result;
@@ -187,13 +195,15 @@ struct cons_pointer add_integer_ratio( struct cons_pointer intarg,
* @exception will return an exception if either `arg1` or `arg2` is not a
* rational number.
*/
-struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1,
+struct cons_pointer divide_ratio_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg1,
struct cons_pointer arg2 ) {
- // TODO: this now has to work if `arg1` is an integer
- struct cons_pointer i =
- make_ratio( pointer2cell( arg2 ).payload.ratio.divisor,
- pointer2cell( arg2 ).payload.ratio.dividend ), result =
- multiply_ratio_ratio( arg1, i );
+ struct cons_pointer i = make_ratio( frame_pointer,
+ pointer2cell( arg2 ).payload.
+ ratio.divisor,
+ pointer2cell( arg2 ).payload.
+ ratio.dividend ), result =
+ multiply_ratio_ratio( frame_pointer, arg1, i );
dec_ref( i );
@@ -206,10 +216,9 @@ struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1,
* @exception will return an exception if either `arg1` or `arg2` is not a
* rational number.
*/
-struct cons_pointer multiply_ratio_ratio( struct
+struct cons_pointer multiply_ratio_ratio( struct cons_pointer frame_pointer, struct
cons_pointer arg1, struct
cons_pointer arg2 ) {
- // TODO: this now has to work if arg1 is an integer
struct cons_pointer result;
debug_print( L"multiply_ratio_ratio( arg1 = ", DEBUG_ARITH );
@@ -232,9 +241,9 @@ struct cons_pointer multiply_ratio_ratio( struct
ddrv = dd1v * dd2v, drrv = dr1v * dr2v;
struct cons_pointer unsimplified =
- make_ratio( make_integer( ddrv, NIL ),
+ make_ratio( frame_pointer, make_integer( ddrv, NIL ),
make_integer( drrv, NIL ) );
- result = simplify_ratio( unsimplified );
+ result = simplify_ratio( frame_pointer, unsimplified );
if ( !eq( unsimplified, result ) ) {
dec_ref( unsimplified );
@@ -243,7 +252,7 @@ struct cons_pointer multiply_ratio_ratio( struct
result =
throw_exception( c_string_to_lisp_string
( L"Shouldn't happen: bad arg to multiply_ratio_ratio" ),
- NIL );
+ frame_pointer );
}
return result;
@@ -255,15 +264,15 @@ struct cons_pointer multiply_ratio_ratio( struct
* `ratarg`.
* @exception if either `intarg` or `ratarg` is not of the expected type.
*/
-struct cons_pointer multiply_integer_ratio( struct cons_pointer intarg,
+struct cons_pointer multiply_integer_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer intarg,
struct cons_pointer ratarg ) {
struct cons_pointer result;
if ( integerp( intarg ) && ratiop( ratarg ) ) {
- // TODO: no longer works; fix
struct cons_pointer one = make_integer( 1, NIL ),
- ratio = make_ratio( intarg, one );
- result = multiply_ratio_ratio( ratio, ratarg );
+ ratio = make_ratio( frame_pointer, intarg, one );
+ result = multiply_ratio_ratio( frame_pointer, ratio, ratarg );
dec_ref( one );
dec_ref( ratio );
@@ -271,7 +280,7 @@ struct cons_pointer multiply_integer_ratio( struct cons_pointer intarg,
result =
throw_exception( c_string_to_lisp_string
( L"Shouldn't happen: bad arg to multiply_integer_ratio" ),
- NIL );
+ frame_pointer );
}
return result;
@@ -284,10 +293,11 @@ struct cons_pointer multiply_integer_ratio( struct cons_pointer intarg,
* @exception will return an exception if either `arg1` or `arg2` is not a
* rational number.
*/
-struct cons_pointer subtract_ratio_ratio( struct cons_pointer arg1,
+struct cons_pointer subtract_ratio_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg1,
struct cons_pointer arg2 ) {
- struct cons_pointer i = negative( arg2 ),
- result = add_ratio_ratio( arg1, i );
+ struct cons_pointer i = negative( frame_pointer, arg2 ),
+ result = add_ratio_ratio( frame_pointer, arg1, i );
dec_ref( i );
@@ -301,13 +311,14 @@ struct cons_pointer subtract_ratio_ratio( struct cons_pointer arg1,
* `frame_pointer`.
* @exception if either `dividend` or `divisor` is not an integer.
*/
-struct cons_pointer make_ratio( struct cons_pointer dividend,
+struct cons_pointer make_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer dividend,
struct cons_pointer divisor ) {
struct cons_pointer result;
if ( integerp( dividend ) && integerp( divisor ) ) {
inc_ref( dividend );
inc_ref( divisor );
- result = allocate_cell( RATIOTV );
+ result = allocate_cell( RATIOTAG );
struct cons_space_object *cell = &pointer2cell( result );
cell->payload.ratio.dividend = dividend;
cell->payload.ratio.divisor = divisor;
@@ -315,28 +326,10 @@ struct cons_pointer make_ratio( struct cons_pointer dividend,
result =
throw_exception( c_string_to_lisp_string
( L"Dividend and divisor of a ratio must be integers" ),
- NIL );
+ frame_pointer );
}
debug_dump_object( result, DEBUG_ARITH );
- return result;
-}
-
-/**
- * True if a and be are identical ratios, else false.
- */
-bool equal_ratio_ratio( struct cons_pointer a, struct cons_pointer b ) {
- bool result = false;
-
- if ( ratiop( a ) && ratiop( b ) ) {
- struct cons_space_object *cell_a = &pointer2cell( a );
- struct cons_space_object *cell_b = &pointer2cell( b );
-
- result = equal_integer_integer( cell_a->payload.ratio.dividend,
- cell_b->payload.ratio.dividend ) &&
- equal_integer_integer( cell_a->payload.ratio.divisor,
- cell_b->payload.ratio.divisor );
- }
return result;
}
diff --git a/src/arith/ratio.h b/src/arith/ratio.h
index 9068bfb..5a3b0d6 100644
--- a/src/arith/ratio.h
+++ b/src/arith/ratio.h
@@ -11,29 +11,36 @@
#ifndef __ratio_h
#define __ratio_h
-struct cons_pointer simplify_ratio( struct cons_pointer arg );
+struct cons_pointer simplify_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg );
-struct cons_pointer add_ratio_ratio( struct cons_pointer arg1,
+struct cons_pointer add_ratio_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg1,
struct cons_pointer arg2 );
-struct cons_pointer add_integer_ratio( struct cons_pointer intarg,
+struct cons_pointer add_integer_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer intarg,
struct cons_pointer ratarg );
-struct cons_pointer divide_ratio_ratio( struct cons_pointer arg1,
+struct cons_pointer divide_ratio_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg1,
struct cons_pointer arg2 );
-struct cons_pointer multiply_ratio_ratio( struct cons_pointer arg1, struct
+struct cons_pointer multiply_ratio_ratio( struct cons_pointer frame_pointer, struct
+ cons_pointer arg1, struct
cons_pointer arg2 );
-struct cons_pointer multiply_integer_ratio( struct cons_pointer intarg,
+struct cons_pointer multiply_integer_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer intarg,
struct cons_pointer ratarg );
-struct cons_pointer subtract_ratio_ratio( struct cons_pointer arg1,
+struct cons_pointer subtract_ratio_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer arg1,
struct cons_pointer arg2 );
-struct cons_pointer make_ratio( struct cons_pointer dividend,
+struct cons_pointer make_ratio( struct cons_pointer frame_pointer,
+ struct cons_pointer dividend,
struct cons_pointer divisor );
-bool equal_ratio_ratio( struct cons_pointer a, struct cons_pointer b );
#endif
diff --git a/src/arith/real.c b/src/arith/real.c
index 34d29d0..84ba899 100644
--- a/src/arith/real.c
+++ b/src/arith/real.c
@@ -7,10 +7,10 @@
* Licensed under GPL version 2.0, or, at your option, any later version.
*/
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
+#include "conspage.h"
+#include "consspaceobject.h"
#include "debug.h"
-#include "io/read.h"
+#include "read.h"
/**
* Allocate a real number cell representing this value and return a cons
@@ -19,7 +19,7 @@
* @return a real number cell wrapping this value.
*/
struct cons_pointer make_real( long double value ) {
- struct cons_pointer result = allocate_cell( REALTV );
+ struct cons_pointer result = allocate_cell( REALTAG );
struct cons_space_object *cell = &pointer2cell( result );
cell->payload.real.value = value;
diff --git a/src/authorise.c b/src/authorise.c
deleted file mode 100644
index afd730d..0000000
--- a/src/authorise.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * authorised.c
- *
- * For now, a dummy authorising everything.
- *
- * (c) 2021 Simon Brooke
- * Licensed under GPL version 2.0, or, at your option, any later version.
- */
-
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
-
-
-/**
- * TODO: does nothing, yet. What it should do is access a magic value in the
- * runtime environment and check that it is identical to something on this `acl`
- */
-struct cons_pointer authorised( struct cons_pointer target,
- struct cons_pointer acl ) {
- if ( nilp( acl ) ) {
- acl = pointer2cell( target ).access;
- }
- return TRUE;
-}
diff --git a/src/authorise.h b/src/authorise.h
deleted file mode 100644
index 6c55b32..0000000
--- a/src/authorise.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * authorise.h
- *
- * Basic implementation of a authorisation.
- *
- * (c) 2021 Simon Brooke
- * Licensed under GPL version 2.0, or, at your option, any later version.
- */
-
-#ifndef __psse_authorise_h
-#define __psse_authorise_h
-
-struct cons_pointer authorised( struct cons_pointer target,
- struct cons_pointer acl );
-
-#endif
diff --git a/src/debug.c b/src/debug.c
index 233e154..c8b9771 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -18,11 +18,11 @@
#include
#include
-#include "memory/consspaceobject.h"
+#include "consspaceobject.h"
#include "debug.h"
-#include "memory/dump.h"
-#include "io/io.h"
-#include "io/print.h"
+#include "dump.h"
+#include "io.h"
+#include "print.h"
/**
* the controlling flags for `debug_print`; set in `init.c`, q.v.
diff --git a/src/init.c b/src/init.c
index 676964f..dbfdd5d 100644
--- a/src/init.c
+++ b/src/init.c
@@ -20,20 +20,18 @@
#include
#include "version.h"
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
-#include "memory/stack.h"
+#include "conspage.h"
+#include "consspaceobject.h"
#include "debug.h"
-#include "memory/hashmap.h"
-#include "ops/intern.h"
-#include "io/io.h"
-#include "ops/lispops.h"
-#include "ops/meta.h"
-#include "arith/peano.h"
-#include "io/print.h"
+#include "intern.h"
+#include "io.h"
+#include "lispops.h"
+#include "map.h"
+#include "meta.h"
+#include "peano.h"
+#include "print.h"
#include "repl.h"
-#include "io/fopen.h"
-#include "time/psse_time.h"
+#include "psse_time.h"
// extern char *optarg; /* defined in unistd.h */
@@ -86,9 +84,8 @@ void bind_value( wchar_t *name, struct cons_pointer value ) {
dec_ref( n );
}
-void print_banner( ) {
- fwprintf( stdout, L"Post-Scarcity Software Environment version %s\n\n",
- VERSION );
+void print_banner() {
+ fwprintf(stdout, L"Post-Scarcity Software Environment version %s\n\n", VERSION);
}
/**
@@ -96,24 +93,22 @@ void print_banner( ) {
*
* @stream the stream to print to.
*/
-void print_options( FILE * stream ) {
- fwprintf( stream, L"Expected options are:\n" );
- fwprintf( stream,
- L"\t-d\tDump memory to standard out at end of run (copious!);\n" );
- fwprintf( stream, L"\t-h\tPrint this message and exit;\n" );
- fwprintf( stream, L"\t-p\tShow a prompt (default is no prompt);\n" );
- fwprintf( stream,
- L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n" );
- fwprintf( stream, L"\t\tWhere bits are interpreted as follows:\n" );
- fwprintf( stream, L"\t\t1\tALLOC;\n" );
- fwprintf( stream, L"\t\t2\tARITH;\n" );
- fwprintf( stream, L"\t\t4\tBIND;\n" );
- fwprintf( stream, L"\t\t8\tBOOTSTRAP;\n" );
- fwprintf( stream, L"\t\t16\tEVAL;\n" );
- fwprintf( stream, L"\t\t32\tINPUT/OUTPUT;\n" );
- fwprintf( stream, L"\t\t64\tLAMBDA;\n" );
- fwprintf( stream, L"\t\t128\tREPL;\n" );
- fwprintf( stream, L"\t\t256\tSTACK.\n" );
+void print_options(FILE* stream) {
+ fwprintf(stream, L"Expected options are:\n");
+ fwprintf(stream, L"\t-d\tDump memory to standard out at end of run (copious!);\n");
+ fwprintf(stream, L"\t-h\tPrint this message and exit;\n");
+ fwprintf(stream, L"\t-p\tShow a prompt (default is no prompt);\n");
+ fwprintf(stream, L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n");
+ fwprintf(stream, L"\t\tWhere bits are interpreted as follows:\n");
+ fwprintf(stream, L"\t\t1\tALLOC;\n");
+ fwprintf(stream, L"\t\t2\tARITH;\n");
+ fwprintf(stream, L"\t\t4\tBIND;\n");
+ fwprintf(stream, L"\t\t8\tBOOTSTRAP;\n");
+ fwprintf(stream, L"\t\t16\tEVAL;\n");
+ fwprintf(stream, L"\t\t32\tINPUT/OUTPUT;\n");
+ fwprintf(stream, L"\t\t64\tLAMBDA;\n");
+ fwprintf(stream, L"\t\t128\tREPL;\n");
+ fwprintf(stream, L"\t\t256\tSTACK.\n");
}
/**
@@ -137,8 +132,8 @@ int main( int argc, char *argv[] ) {
dump_at_end = true;
break;
case 'h':
- print_banner( );
- print_options( stdout );
+ print_banner();
+ print_options(stdout);
exit( 0 );
break;
case 'p':
@@ -149,14 +144,14 @@ int main( int argc, char *argv[] ) {
break;
default:
fwprintf( stderr, L"Unexpected option %c\n", option );
- print_options( stderr );
+ print_options(stderr);
exit( 1 );
break;
}
}
if ( show_prompt ) {
- print_banner( );
+ print_banner();
}
debug_print( L"About to initialise cons pages\n", DEBUG_BOOTSTRAP );
@@ -165,9 +160,6 @@ int main( int argc, char *argv[] ) {
debug_print( L"Initialised cons pages, about to bind\n", DEBUG_BOOTSTRAP );
-// TODO: oblist-as-hashmap (which is what we ultimately need) is failing hooribly
-// oblist = inc_ref( make_hashmap( 32, NIL, TRUE ) );
-
/*
* privileged variables (keywords)
*/
@@ -222,7 +214,6 @@ int main( int argc, char *argv[] ) {
*/
bind_function( L"absolute", &lisp_absolute );
bind_function( L"add", &lisp_add );
- bind_function( L"append", &lisp_append );
bind_function( L"apply", &lisp_apply );
bind_function( L"assoc", &lisp_assoc );
bind_function( L"car", &lisp_car );
@@ -234,12 +225,8 @@ int main( int argc, char *argv[] ) {
bind_function( L"equal", &lisp_equal );
bind_function( L"eval", &lisp_eval );
bind_function( L"exception", &lisp_exception );
- bind_function( L"get-hash", &lisp_get_hash );
- bind_function( L"hashmap", lisp_make_hashmap );
bind_function( L"inspect", &lisp_inspect );
- bind_function( L"keys", &lisp_keys );
- bind_function( L"list", &lisp_list );
- bind_function( L"mapcar", &lisp_mapcar );
+ bind_function( L"make-map", &lisp_make_map);
bind_function( L"meta", &lisp_metadata );
bind_function( L"metadata", &lisp_metadata );
bind_function( L"multiply", &lisp_multiply );
@@ -247,8 +234,7 @@ int main( int argc, char *argv[] ) {
bind_function( L"oblist", &lisp_oblist );
bind_function( L"open", &lisp_open );
bind_function( L"print", &lisp_print );
- bind_function( L"put!", lisp_hashmap_put );
- bind_function( L"put-all!", &lisp_hashmap_put_all );
+ bind_function( L"progn", &lisp_progn );
bind_function( L"read", &lisp_read );
bind_function( L"read-char", &lisp_read_char );
bind_function( L"repl", &lisp_repl );
@@ -271,18 +257,14 @@ int main( int argc, char *argv[] ) {
bind_special( L"cond", &lisp_cond );
bind_special( L"lambda", &lisp_lambda );
bind_special( L"\u03bb", &lisp_lambda ); // λ
- bind_special( L"let", &lisp_let );
bind_special( L"nlambda", &lisp_nlambda );
bind_special( L"n\u03bb", &lisp_nlambda );
bind_special( L"progn", &lisp_progn );
bind_special( L"quote", &lisp_quote );
bind_special( L"set!", &lisp_set_shriek );
- bind_special( L"try", &lisp_try );
debug_print( L"Initialised oblist\n", DEBUG_BOOTSTRAP );
debug_dump_object( oblist, DEBUG_BOOTSTRAP );
-
repl( show_prompt );
-
debug_print( L"Freeing oblist\n", DEBUG_BOOTSTRAP );
dec_ref( oblist );
debug_dump_object( oblist, DEBUG_BOOTSTRAP );
@@ -290,7 +272,6 @@ int main( int argc, char *argv[] ) {
dump_pages( file_to_url_file( stdout ) );
}
- summarise_allocation( );
curl_global_cleanup( );
return ( 0 );
}
diff --git a/src/io/fopen.c b/src/io/fopen.c
index e4fafdd..d3ece5c 100644
--- a/src/io/fopen.c
+++ b/src/io/fopen.c
@@ -47,12 +47,12 @@
#include
-#include "io/fopen.h"
+#include "fopen.h"
#ifdef FOPEN_STANDALONE
CURLSH *io_share;
#else
-#include "memory/consspaceobject.h"
-#include "io/io.h"
+#include "consspaceobject.h"
+#include "io.h"
#include "utils.h"
#endif
@@ -213,7 +213,7 @@ URL_FILE *url_fopen( const char *url, const char *operation ) {
file->handle.file = fopen( url, operation );
if ( file->handle.file ) {
file->type = CFTYPE_FILE; /* marked as file */
- } else if ( index_of( ':', url ) > -1 ) {
+ } else if ( index_of(':', url ) > -1 ) {
file->type = CFTYPE_CURL; /* marked as URL */
file->handle.curl = curl_easy_init( );
diff --git a/src/io/io.c b/src/io/io.c
index d01f788..5065044 100644
--- a/src/io/io.c
+++ b/src/io/io.c
@@ -28,13 +28,13 @@
#include
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
+#include "conspage.h"
+#include "consspaceobject.h"
#include "debug.h"
-#include "io/fopen.h"
-#include "arith/integer.h"
-#include "ops/intern.h"
-#include "ops/lispops.h"
+#include "fopen.h"
+#include "integer.h"
+#include "intern.h"
+#include "lispops.h"
#include "utils.h"
/**
@@ -56,6 +56,8 @@ wint_t ungotten = 0;
* @return 0 on success; any other value means failure.
*/
int io_init( ) {
+ CURL *curl;
+ CURLcode res;
int result = curl_global_init( CURL_GLOBAL_SSL );
io_share = curl_share_init( );
@@ -164,7 +166,6 @@ wint_t url_fgetwc( URL_FILE * input ) {
debug_print( L"url_fgetwc: back from url_fgets\n",
DEBUG_IO );
int c = ( int ) cbuff[0];
- // TODO: risk of reading off cbuff?
debug_printf( DEBUG_IO,
L"url_fgetwc: cbuff is '%s'; (first) character = %d (%c)\n",
cbuff, c, c & 0xf7 );
@@ -176,13 +177,13 @@ wint_t url_fgetwc( URL_FILE * input ) {
* E0 to EF hex (224 to 239): first byte of a three-byte sequence.
* F0 to FF hex (240 to 255): first byte of a four-byte sequence.
*/
- if ( c <= 0xf7 ) {
+ if ( c <= 0x07 ) {
count = 1;
- } else if ( c >= 0xc2 && c <= 0xdf ) {
+ } else if ( c >= '0xc2' && c <= '0xdf' ) {
count = 2;
- } else if ( c >= 0xe0 && c <= 0xef ) {
+ } else if ( c >= '0xe0' && c <= '0xef' ) {
count = 3;
- } else if ( c >= 0xf0 && c <= 0xff ) {
+ } else if ( c >= '0xf0' && c <= '0xff' ) {
count = 4;
}
@@ -264,7 +265,7 @@ struct cons_pointer add_meta_integer( struct cons_pointer meta, wchar_t *key,
struct cons_pointer add_meta_string( struct cons_pointer meta, wchar_t *key,
char *value ) {
- value = trim( value );
+ value = trim( value);
wchar_t buffer[strlen( value ) + 1];
mbstowcs( buffer, value, strlen( value ) + 1 );
@@ -279,8 +280,9 @@ struct cons_pointer add_meta_time( struct cons_pointer meta, wchar_t *key,
char datestring[256];
strftime( datestring,
- sizeof( datestring ),
- nl_langinfo( D_T_FMT ), localtime( value ) );
+ sizeof( datestring ),
+ nl_langinfo( D_T_FMT ),
+ localtime( value ) );
return add_meta_string( meta, key, datestring );
}
@@ -389,28 +391,10 @@ void collect_meta( struct cons_pointer stream, char *url ) {
}
/* this is destructive change before the cell is released into the
- * wild, and consequently permissible, just. */
+ * wild, and consequently permissible, just. */
cell->payload.stream.meta = meta;
}
-/**
- * Resutn the current default input, or of `inputp` is false, output stream from
- * this `env`ironment.
- */
-struct cons_pointer get_default_stream( bool inputp, struct cons_pointer env ) {
- struct cons_pointer result = NIL;
- struct cons_pointer stream_name =
- c_string_to_lisp_symbol( inputp ? L"*in*" : L"*out*" );
-
- inc_ref( stream_name );
-
- result = c_assoc( stream_name, env );
-
- dec_ref( stream_name );
-
- return result;
-}
-
/**
* Function: return a stream open on the URL indicated by the first argument;
@@ -439,23 +423,20 @@ lisp_open( struct stack_frame *frame, struct cons_pointer frame_pointer,
URL_FILE *stream = url_fopen( url, "r" );
debug_printf( DEBUG_IO,
- L"lisp_open: stream @ %ld, stream type = %d, stream handle = %ld\n",
- ( long int ) &stream, ( int ) stream->type,
- ( long int ) stream->handle.file );
+ L"lisp_open: stream @ %d, stream type = %d, stream handle = %d\n",
+ (int) &stream, (int)stream->type, (int)stream->handle.file);
- switch ( stream->type ) {
+ switch (stream->type) {
case CFTYPE_NONE:
- return
- make_exception( c_string_to_lisp_string
- ( L"Could not open stream" ),
- frame_pointer );
+ return make_exception(
+ c_string_to_lisp_string( L"Could not open stream"),
+ frame_pointer);
break;
case CFTYPE_FILE:
- if ( stream->handle.file == NULL ) {
- return
- make_exception( c_string_to_lisp_string
- ( L"Could not open file" ),
- frame_pointer );
+ if (stream->handle.file == NULL) {
+ return make_exception(
+ c_string_to_lisp_string( L"Could not open file"),
+ frame_pointer);
}
break;
case CFTYPE_CURL:
@@ -502,8 +483,8 @@ lisp_read_char( struct stack_frame *frame, struct cons_pointer frame_pointer,
if ( readp( frame->arg[0] ) ) {
result =
make_string( url_fgetwc
- ( pointer2cell( frame->arg[0] ).payload.stream.
- stream ), NIL );
+ ( pointer2cell( frame->arg[0] ).payload.
+ stream.stream ), NIL );
}
return result;
diff --git a/src/io/io.h b/src/io/io.h
index f350c13..33f733f 100644
--- a/src/io/io.h
+++ b/src/io/io.h
@@ -21,8 +21,6 @@ URL_FILE *file_to_url_file( FILE * f );
wint_t url_fgetwc( URL_FILE * input );
wint_t url_ungetwc( wint_t wc, URL_FILE * input );
-struct cons_pointer get_default_stream( bool inputp, struct cons_pointer env );
-
struct cons_pointer
lisp_close( struct stack_frame *frame, struct cons_pointer frame_pointer,
struct cons_pointer env );
diff --git a/src/io/print.c b/src/io/print.c
index 8f4b88e..f0db8cd 100644
--- a/src/io/print.c
+++ b/src/io/print.c
@@ -17,15 +17,15 @@
#include
#include
-#include "memory/conspage.h"
-#include "memory/consspaceobject.h"
-#include "memory/hashmap.h"
-#include "arith/integer.h"
-#include "ops/intern.h"
-#include "memory/stack.h"
-#include "io/print.h"
-#include "time/psse_time.h"
-#include "memory/vectorspace.h"
+#include "conspage.h"
+#include "consspaceobject.h"
+#include "integer.h"
+#include "intern.h"
+#include "map.h"
+#include "stack.h"
+#include "print.h"
+#include "psse_time.h"
+#include "vectorspace.h"
/**
* print all the characters in the symbol or string indicated by `pointer`
@@ -88,38 +88,40 @@ void print_list( URL_FILE * output, struct cons_pointer pointer ) {
url_fputws( L")", output );
}
-void print_map( URL_FILE * output, struct cons_pointer map ) {
- if ( hashmapp( map ) ) {
- struct vector_space_object *vso = pointer_to_vso( map );
- url_fputwc( btowc( '{' ), output );
+void print_map( URL_FILE * output, struct cons_pointer map) {
+ if ( vectorpointp( map)) {
+ struct vector_space_object *vso = pointer_to_vso( map);
- for ( struct cons_pointer ks = hashmap_keys( map ); !nilp( ks );
- ks = c_cdr( ks ) ) {
- struct cons_pointer key = c_car( ks );
- print( output, key );
- url_fputwc( btowc( ' ' ), output );
- print( output, hashmap_get( map, key ) );
+ if ( mapp( vso ) ) {
+ url_fputwc( btowc( '{' ), output );
- if ( !nilp( c_cdr( ks ) ) ) {
- url_fputws( L", ", output );
+ for ( struct cons_pointer ks = keys( map);
+ !nilp( ks); ks = c_cdr( ks)) {
+ print( output, c_car( ks));
+ url_fputwc( btowc( ' ' ), output );
+ print( output, c_assoc( c_car( ks), map));
+
+ if ( !nilp( c_cdr( ks))) {
+ url_fputws( L", ", output );
+ }
}
- }
- url_fputwc( btowc( '}' ), output );
+ url_fputwc( btowc( '}' ), output );
+ }
}
}
-void print_vso( URL_FILE * output, struct cons_pointer pointer ) {
- struct vector_space_object *vso = pointer_to_vso( pointer );
- switch ( vso->header.tag.value ) {
- case HASHTV:
- print_map( output, pointer );
+
+void print_vso( URL_FILE * output, struct cons_pointer pointer) {
+ struct vector_space_object *vso =
+ pointer2cell( pointer ).payload.vectorp.address;
+
+ switch ( vso->header.tag.value) {
+ case MAPTV:
+ print_map( output, pointer);
break;
- // \todo: others.
- default:
- fwprintf( stderr, L"Unrecognised vector-space type '%d'\n",
- vso->header.tag.value );
+ // \todo: others.
}
}
@@ -130,14 +132,14 @@ void print_128bit( URL_FILE * output, __int128_t n ) {
if ( n == 0 ) {
fwprintf( stderr, L"0" );
} else {
- char str[40] = { 0 }; // log10(1 << 128) + '\0'
+ char str[40] = { 0 }; // log10(1 << 128) + '\0'
char *s = str + sizeof( str ) - 1; // start at the end
while ( n != 0 ) {
if ( s == str )
- return; // never happens
+ return; // never happens
*--s = "0123456789"[n % 10]; // save last digit
- n /= 10; // drop it
+ n /= 10; // drop it
}
url_fwprintf( output, L"%s", s );
}
@@ -165,9 +167,9 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
dump_stack_trace( output, pointer );
break;
case FUNCTIONTV:
- url_fputws( L"', output );
+ url_fputws( L"', output);
break;
case INTEGERTV:{
struct cons_pointer s = integer_to_string( pointer, 10 );
@@ -181,9 +183,8 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
print_string_contents( output, pointer );
break;
case LAMBDATV:{
- url_fputws( L"', output );
}
break;
case NILTV:
url_fwprintf( output, L"nil" );
break;
case NLAMBDATV:{
- url_fputws( L"', output );
}
break;
case RATIOTV:
@@ -218,8 +216,8 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
break;
case READTV:
url_fwprintf( output, L"', output );
+ print( output, cell.payload.stream.meta);
+ url_fputwc( L'>', output);
break;
case REALTV:
/* \todo using the C heap is a bad plan because it will fragment.
@@ -245,26 +243,26 @@ struct cons_pointer print( URL_FILE * output, struct cons_pointer pointer ) {
break;
case SPECIALTV:
url_fwprintf( output, L"', output );
+ print( output, cell.payload.special.meta);
+ url_fputwc( L'>', output);
break;
case TIMETV:
url_fwprintf( output, L"', output );
+ print_string( output, time_to_string( pointer));
+ url_fputws( L"; ", output);
+ print_128bit( output, pointer2cell(pointer).payload.time.value);
+ url_fputwc( L'>', output);
break;
case TRUETV:
url_fwprintf( output, L"t" );
break;
case VECTORPOINTTV:
- print_vso( output, pointer );
+ print_vso( output, pointer);
break;
case WRITETV:
url_fwprintf( output, L"