405 - permit loading just low levels of codebase

When I'm doing extensive surgery to the internals I want to avoid
loading higher levels; they aren't expected to work. But I don't want to
keep different levels in separate files just for that. And I definitely
don't want to put low-level stuff first. Now I can influence loading in
a cross-cutting manner by creating sections with numbers:

  (section 100
    ...code...)

And disabling them by running:

  $ ./anarki/arc 99 mu.arc.t

Currently we load all mu 'system software' in level 100, so running at
level 99 sidesteps them. Lower levels coming soon.

But most of the time we don't need to worry about levels, and the 'mu'
script lets us forget about them. Just run .mu files with:

  $ ./mu factorial.mu

To run tests:

  $ ./mu test mu.arc.t
This commit is contained in:
Kartik K. Agaram 2014-12-13 00:33:20 -08:00
parent bd7c17ea21
commit 4f9f75ddcf
6 changed files with 76 additions and 8 deletions

View File

@ -113,7 +113,7 @@ the system doesn't recognize gets silently ignored.
Try this program out now:
```shell
$ ./anarki/arc mu.arc factorial.mu
$ ./mu factorial.mu
result: 120 # factorial of 5
... # ignore the memory dump for now
```
@ -159,7 +159,7 @@ inserting code at them.
Another example, this time with concurrency.
```shell
$ ./anarki/arc mu.arc fork.mu
$ ./mu fork.mu
```
Notice that it repeatedly prints either '34' or '35' at random. Hit ctrl-c to
@ -168,7 +168,7 @@ stop.
Yet another example forks two 'routines' that communicate over a channel:
```shell
$ ./anarki/arc mu.arc channel.mu
$ ./mu channel.mu
produce: 0
produce: 1
produce: 2
@ -200,7 +200,7 @@ allocator and a few other places).
Try running the tests:
```shell
$ ./anark/arc mu.arc.t
$ ./mu test mu.arc.t
$ # all tests passed!
```

View File

@ -1,4 +1,6 @@
(load "mu.arc")
(selective-load "mu.arc" section-level)
(section 100
(reset)
(new-trace "new-screen")
@ -26,3 +28,5 @@
(prn "F - newly-allocated screen didn't initialize all of its row lengths")))))
(reset)
) ; section 100 for all editor code

28
load.arc Normal file
View File

@ -0,0 +1,28 @@
; support for dividing arc files into sections of different level, and
; selectively loading just sections at or less than a given level
; usage:
; load.arc [arc files] -- [mu files]
(def selective-load (file (o level 999))
;? (prn "loading @file at level @level")
(fromfile file
(whilet expr (read)
;? (prn car.expr)
(if (is 'section expr.0)
(when (< expr.1 level)
(each x (cut expr 2)
(eval x)))
(eval expr))
;? (prn car.expr " done")
)))
(= section-level 999)
(point break
(each x (map [fromstring _ (read)] cdr.argv)
(if (isa x 'int)
(= section-level x)
(is '-- x)
(break) ; later args are mu files
:else
(selective-load string.x section-level))))

16
mu Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
# Run this from the mu directory.
#
# Wrapper to allow selectively running parts of the mu codebase/tests.
#
# Usage:
# mu [mu files]
# mu test [arc files]
if [[ $1 == "test" ]]
then
shift
./anarki/arc load.arc "$@" # test currently assumed to be arc files rather than mu files
else
./anarki/arc load.arc mu.arc -- "$@" # mu files from args
fi

8
mu.arc
View File

@ -982,6 +982,8 @@
;; system software
(section 100
(init-fn maybe-coerce
((default-scope scope-address) <- new (scope literal) (30 literal))
((x tagged-value-address) <- new (tagged-value literal))
@ -1306,6 +1308,8 @@
}
(reply (result string-address)))
) ; section 100 for system software
(def canon (table)
(sort (compare < [tostring (prn:car _)]) (as cons table)))
@ -1357,8 +1361,8 @@
;; load all provided files and start at 'main'
(reset)
(awhen cdr.argv
(map add-code:readfile it)
(awhen (pos "--" argv)
(map add-code:readfile (cut argv (+ it 1)))
;? (= dump-trace* (obj whitelist '("run" "schedule" "add")))
;? (freeze-functions)
;? (prn function*!factorial)

View File

@ -113,7 +113,7 @@
; Other than that, we'll say no more about the code, and focus in the rest of
; this file on the scenarios the code cares about.
(load "mu.arc")
(selective-load "mu.arc" section-level)
;? (quit)
; Our language is assembly-like in that functions consist of series of
@ -788,6 +788,8 @@
4 34 5 35 6 36))
(prn "F - ops can operate on records with fields spanning multiple locations"))
(section 100
; A special kind of record is the 'tagged type'. It lets us represent
; dynamically typed values, which save type information in memory rather than
; in the code to use them. This will let us do things like create heterogenous
@ -938,6 +940,8 @@
(~is (memory* (+ third 2) nil)))))))
(prn "F - 'new-list' can construct a list of integers")))
) ; section 100
;; Functions
;
; Just like the table of types is centralized, functions are conceptualized as
@ -1967,6 +1971,8 @@
(prn "F - 'len' accesses length of array address"))
;? (quit)
(section 100
;; Dynamic dispatch
;
; Putting it all together, here's how you define generic functions that run
@ -2086,6 +2092,8 @@
(if (~and (is memory*.3 t) (is memory*.12 37))
(prn "F - different calls can exercise different clauses of the same function"))
) ; section 100
;; Concurrency
;
; A rudimentary process scheduler. You can 'run' multiple functions at once,
@ -2470,6 +2478,8 @@
(if (no rep.routine!error)
(prn "F - 'index' throws an error if out of bounds")))
(section 100
;; Synchronization
;
; Mu synchronizes using channels rather than locks, like Erlang and Go.
@ -2778,6 +2788,8 @@
(prn "F - channels are meant to be shared between routines"))
;? (quit)
) ; section 100
;; Separating concerns
;
; Lightweight tools can also operate on quoted lists of statements surrounded
@ -3190,6 +3202,8 @@
:else
(recur (+ addr 1) (+ idx 1))))))
(section 100 ; string utilities
(reset)
(new-trace "string-new")
(add-code '((function main [
@ -3295,6 +3309,8 @@
(if (~memory-contains-array memory*.5 "hello, abc, def, and ghi!")
(prn "F - 'interpolate' splices in any number of strings"))
) ; section 100 for string utilities
;; unit tests for various helpers
; addr