diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-01-19 23:18:03 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-01-19 23:18:03 -0800 |
commit | 455fbac64f101b05f7eaca89b84470569e4df3fd (patch) | |
tree | 32cfd5b092ad86086e4d15992bb10fd06a12bf13 /edit/005-sandbox.mu | |
parent | 7163e18a774781c62f0c0542e4cb9037f6a71d22 (diff) | |
download | mu-455fbac64f101b05f7eaca89b84470569e4df3fd.tar.gz |
2576 - distinguish allocated addresses from others
This is the one major refinement on the C programming model I'm planning to introduce in mu. Instead of Rust's menagerie of pointer types and static checking, I want to introduce just one new type, and use it to perform ref-counting at runtime. So far all we're doing is updating new's interface. The actual ref-counting implementation is next. One implication: I might sometimes need duplicate implementations for a recipe with allocated vs vanilla addresses of the same type. So far it seems I can get away with just always passing in allocated addresses; the situations when you want to pass an unallocated address to a recipe should be few and far between.
Diffstat (limited to 'edit/005-sandbox.mu')
-rw-r--r-- | edit/005-sandbox.mu | 152 |
1 files changed, 76 insertions, 76 deletions
diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu index 3929fb76..3095e865 100644 --- a/edit/005-sandbox.mu +++ b/edit/005-sandbox.mu @@ -7,10 +7,10 @@ recipe! main [ local-scope open-console - initial-recipe:address:array:character <- restore [recipes.mu] - initial-sandbox:address:array:character <- new [] + initial-recipe:address:shared:array:character <- restore [recipes.mu] + initial-sandbox:address:shared:array:character <- new [] hide-screen 0/screen - env:address:programming-environment-data <- new-programming-environment 0/screen, initial-recipe, initial-sandbox + env:address:shared:programming-environment-data <- new-programming-environment 0/screen, initial-recipe, initial-sandbox env <- restore-sandboxes env render-all 0/screen, env event-loop 0/screen, 0/console, env @@ -18,35 +18,35 @@ recipe! main [ ] container programming-environment-data [ - sandbox:address:sandbox-data # list of sandboxes, from top to bottom + sandbox:address:shared:sandbox-data # list of sandboxes, from top to bottom ] container sandbox-data [ - data:address:array:character - response:address:array:character - expected-response:address:array:character + data:address:shared:array:character + response:address:shared:array:character + expected-response:address:shared:array:character # coordinates to track clicks starting-row-on-screen:number code-ending-row-on-screen:number # past end of code response-starting-row-on-screen:number - screen:address:screen # prints in the sandbox go here - next-sandbox:address:sandbox-data + screen:address:shared:screen # prints in the sandbox go here + next-sandbox:address:shared:sandbox-data ] scenario run-and-show-results [ trace-until 100/app # trace too long assume-screen 100/width, 15/height # recipe editor is empty - 1:address:array:character <- new [] + 1:address:shared:array:character <- new [] # sandbox editor contains an instruction without storing outputs - 2:address:array:character <- new [divide-with-remainder 11, 3] - 3:address:programming-environment-data <- new-programming-environment screen:address:screen, 1:address:array:character, 2:address:array:character + 2:address:shared:array:character <- new [divide-with-remainder 11, 3] + 3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character # run the code in the editors assume-console [ press F4 ] run [ - event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data ] # check that screen prints the results screen-should-contain [ @@ -89,7 +89,7 @@ scenario run-and-show-results [ press F4 ] run [ - event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data ] # check that screen prints the results screen-should-contain [ @@ -115,14 +115,14 @@ after <global-keypress> [ do-run?:boolean <- equal *k, 65532/F4 break-unless do-run? #? $log [F4 pressed] - status:address:array:character <- new [running... ] + status:address:shared:array:character <- new [running... ] screen <- update-status screen, status, 245/grey error?:boolean, env, screen <- run-sandboxes env, screen # F4 might update warnings and results on both sides screen <- render-all screen, env { break-if error? - status:address:array:character <- new [ ] + status:address:shared:array:character <- new [ ] screen <- update-status screen, status, 245/grey } screen <- update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? @@ -130,36 +130,36 @@ after <global-keypress> [ } ] -recipe run-sandboxes env:address:programming-environment-data, screen:address:screen -> errors-found?:boolean, env:address:programming-environment-data, screen:address:screen [ +recipe run-sandboxes env:address:shared:programming-environment-data, screen:address:shared:screen -> errors-found?:boolean, env:address:shared:programming-environment-data, screen:address:shared:screen [ local-scope load-ingredients errors-found?:boolean, env, screen <- update-recipes env, screen reply-if errors-found? # check contents of right editor (sandbox) - current-sandbox:address:editor-data <- get *env, current-sandbox:offset + current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset { - sandbox-contents:address:array:character <- editor-contents current-sandbox + sandbox-contents:address:shared:array:character <- editor-contents current-sandbox break-unless sandbox-contents # if contents exist, first save them # run them and turn them into a new sandbox-data - new-sandbox:address:sandbox-data <- new sandbox-data:type - data:address:address:array:character <- get-address *new-sandbox, data:offset + new-sandbox:address:shared:sandbox-data <- new sandbox-data:type + data:address:address:shared:array:character <- get-address *new-sandbox, data:offset *data <- copy sandbox-contents # push to head of sandbox list - dest:address:address:sandbox-data <- get-address *env, sandbox:offset - next:address:address:sandbox-data <- get-address *new-sandbox, next-sandbox:offset + dest:address:address:shared:sandbox-data <- get-address *env, sandbox:offset + next:address:address:shared:sandbox-data <- get-address *new-sandbox, next-sandbox:offset *next <- copy *dest *dest <- copy new-sandbox # clear sandbox editor - init:address:address:duplex-list:character <- get-address *current-sandbox, data:offset + init:address:address:shared:duplex-list:character <- get-address *current-sandbox, data:offset *init <- push 167/§, 0/tail - top-of-screen:address:address:duplex-list:character <- get-address *current-sandbox, top-of-screen:offset + top-of-screen:address:address:shared:duplex-list:character <- get-address *current-sandbox, top-of-screen:offset *top-of-screen <- copy *init } # save all sandboxes before running, just in case we die when running save-sandboxes env # run all sandboxes - curr:address:sandbox-data <- get *env, sandbox:offset + curr:address:shared:sandbox-data <- get *env, sandbox:offset { break-unless curr curr <- update-sandbox curr @@ -171,49 +171,49 @@ recipe run-sandboxes env:address:programming-environment-data, screen:address:sc # copy code from recipe editor, persist, load into mu # replaced in a later layer (whereupon errors-found? will actually be set) -recipe update-recipes env:address:programming-environment-data, screen:address:screen -> errors-found?:boolean, env:address:programming-environment-data, screen:address:screen [ +recipe update-recipes env:address:shared:programming-environment-data, screen:address:shared:screen -> errors-found?:boolean, env:address:shared:programming-environment-data, screen:address:shared:screen [ local-scope load-ingredients - recipes:address:editor-data <- get *env, recipes:offset - in:address:array:character <- editor-contents recipes + recipes:address:shared:editor-data <- get *env, recipes:offset + in:address:shared:array:character <- editor-contents recipes save [recipes.mu], in # newlayer: persistence reload in errors-found? <- copy 0/false ] # replaced in a later layer -recipe update-sandbox sandbox:address:sandbox-data -> sandbox:address:sandbox-data [ +recipe update-sandbox sandbox:address:shared:sandbox-data -> sandbox:address:shared:sandbox-data [ local-scope load-ingredients - data:address:array:character <- get *sandbox, data:offset - response:address:address:array:character <- get-address *sandbox, response:offset - fake-screen:address:address:screen <- get-address *sandbox, screen:offset + data:address:shared:array:character <- get *sandbox, data:offset + response:address:address:shared:array:character <- get-address *sandbox, response:offset + fake-screen:address:address:shared:screen <- get-address *sandbox, screen:offset *response, _, *fake-screen <- run-interactive data ] -recipe update-status screen:address:screen, msg:address:array:character, color:number -> screen:address:screen [ +recipe update-status screen:address:shared:screen, msg:address:shared:array:character, color:number -> screen:address:shared:screen [ local-scope load-ingredients screen <- move-cursor screen, 0, 2 screen <- print screen, msg, color, 238/grey/background ] -recipe save-sandboxes env:address:programming-environment-data [ +recipe save-sandboxes env:address:shared:programming-environment-data [ local-scope load-ingredients - current-sandbox:address:editor-data <- get *env, current-sandbox:offset + current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset # first clear previous versions, in case we deleted some sandbox $system [rm lesson/[0-9]* >/dev/null 2>/dev/null] # some shells can't handle '>&' - curr:address:sandbox-data <- get *env, sandbox:offset - suffix:address:array:character <- new [.out] + curr:address:shared:sandbox-data <- get *env, sandbox:offset + suffix:address:shared:array:character <- new [.out] idx:number <- copy 0 { break-unless curr - data:address:array:character <- get *curr, data:offset - filename:address:array:character <- to-text idx + data:address:shared:array:character <- get *curr, data:offset + filename:address:shared:array:character <- to-text idx save filename, data { - expected-response:address:array:character <- get *curr, expected-response:offset + expected-response:address:shared:array:character <- get *curr, expected-response:offset break-unless expected-response filename <- append filename, suffix save filename, expected-response @@ -224,24 +224,24 @@ recipe save-sandboxes env:address:programming-environment-data [ } ] -recipe! render-sandbox-side screen:address:screen, env:address:programming-environment-data -> screen:address:screen [ +recipe! render-sandbox-side screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen [ local-scope load-ingredients #? $log [render sandbox side] trace 11, [app], [render sandbox side] - current-sandbox:address:editor-data <- get *env, current-sandbox:offset + current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset left:number <- get *current-sandbox, left:offset right:number <- get *current-sandbox, right:offset row:number, column:number, screen, current-sandbox <- render screen, current-sandbox clear-screen-from screen, row, column, left, right row <- add row, 1 draw-horizontal screen, row, left, right, 9473/horizontal-double - sandbox:address:sandbox-data <- get *env, sandbox:offset + sandbox:address:shared:sandbox-data <- get *env, sandbox:offset row, screen <- render-sandboxes screen, sandbox, left, right, row clear-rest-of-screen screen, row, left, left, right ] -recipe render-sandboxes screen:address:screen, sandbox:address:sandbox-data, left:number, right:number, row:number -> row:number, screen:address:screen, sandbox:address:sandbox-data [ +recipe render-sandboxes screen:address:shared:screen, sandbox:address:shared:sandbox-data, left:number, right:number, row:number -> row:number, screen:address:shared:screen, sandbox:address:shared:sandbox-data [ local-scope load-ingredients #? $log [render sandbox] @@ -261,16 +261,16 @@ recipe render-sandboxes screen:address:screen, sandbox:address:sandbox-data, lef # render sandbox contents row <- add row, 1 screen <- move-cursor screen, row, left - sandbox-data:address:array:character <- get *sandbox, data:offset + sandbox-data:address:shared:array:character <- get *sandbox, data:offset row, screen <- render-code screen, sandbox-data, left, right, row code-ending-row:address:number <- get-address *sandbox, code-ending-row-on-screen:offset *code-ending-row <- copy row # render sandbox warnings, screen or response, in that order response-starting-row:address:number <- get-address *sandbox, response-starting-row-on-screen:offset - sandbox-response:address:array:character <- get *sandbox, response:offset + sandbox-response:address:shared:array:character <- get *sandbox, response:offset <render-sandbox-results> { - sandbox-screen:address:screen <- get *sandbox, screen:offset + sandbox-screen:address:shared:screen <- get *sandbox, screen:offset empty-screen?:boolean <- fake-screen-is-empty? sandbox-screen break-if empty-screen? row, screen <- render-screen screen, sandbox-screen, left, right, row @@ -287,32 +287,32 @@ recipe render-sandboxes screen:address:screen, sandbox:address:sandbox-data, lef # draw solid line after sandbox draw-horizontal screen, row, left, right, 9473/horizontal-double # draw next sandbox - next-sandbox:address:sandbox-data <- get *sandbox, next-sandbox:offset + next-sandbox:address:shared:sandbox-data <- get *sandbox, next-sandbox:offset row, screen <- render-sandboxes screen, next-sandbox, left, right, row ] # assumes programming environment has no sandboxes; restores them from previous session -recipe restore-sandboxes env:address:programming-environment-data -> env:address:programming-environment-data [ +recipe restore-sandboxes env:address:shared:programming-environment-data -> env:address:shared:programming-environment-data [ local-scope load-ingredients # read all scenarios, pushing them to end of a list of scenarios - suffix:address:array:character <- new [.out] + suffix:address:shared:array:character <- new [.out] idx:number <- copy 0 - curr:address:address:sandbox-data <- get-address *env, sandbox:offset + curr:address:address:shared:sandbox-data <- get-address *env, sandbox:offset { - filename:address:array:character <- to-text idx - contents:address:array:character <- restore filename + filename:address:shared:array:character <- to-text idx + contents:address:shared:array:character <- restore filename break-unless contents # stop at first error; assuming file didn't exist # create new sandbox for file *curr <- new sandbox-data:type - data:address:address:array:character <- get-address **curr, data:offset + data:address:address:shared:array:character <- get-address **curr, data:offset *data <- copy contents # restore expected output for sandbox if it exists { filename <- append filename, suffix contents <- restore filename break-unless contents - expected-response:address:address:array:character <- get-address **curr, expected-response:offset + expected-response:address:address:shared:array:character <- get-address **curr, expected-response:offset *expected-response <- copy contents } +continue @@ -324,19 +324,19 @@ recipe restore-sandboxes env:address:programming-environment-data -> env:address # print the fake sandbox screen to 'screen' with appropriate delimiters # leave cursor at start of next line -recipe render-screen screen:address:screen, sandbox-screen:address:screen, left:number, right:number, row:number -> row:number, screen:address:screen [ +recipe render-screen screen:address:shared:screen, sandbox-screen:address:shared:screen, left:number, right:number, row:number -> row:number, screen:address:shared:screen [ local-scope load-ingredients reply-unless sandbox-screen # print 'screen:' - header:address:array:character <- new [screen:] + header:address:shared:array:character <- new [screen:] row <- render screen, header, left, right, 245/grey, row screen <- move-cursor screen, row, left # start printing sandbox-screen column:number <- copy left s-width:number <- screen-width sandbox-screen s-height:number <- screen-height sandbox-screen - buf:address:array:screen-cell <- get *sandbox-screen, data:offset + buf:address:shared:array:screen-cell <- get *sandbox-screen, data:offset stop-printing:number <- add left, s-width, 3 max-column:number <- min stop-printing, right i:number <- copy 0 @@ -394,19 +394,19 @@ scenario run-updates-results [ trace-until 100/app # trace too long assume-screen 100/width, 12/height # define a recipe (no indent for the 'add' line below so column numbers are more obvious) - 1:address:array:character <- new [ + 1:address:shared:array:character <- new [ recipe foo [ z:number <- add 2, 2 reply z ]] # sandbox editor contains an instruction without storing outputs - 2:address:array:character <- new [foo] - 3:address:programming-environment-data <- new-programming-environment screen:address:screen, 1:address:array:character, 2:address:array:character + 2:address:shared:array:character <- new [foo] + 3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character # run the code in the editors assume-console [ press F4 ] - event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data screen-should-contain [ . run (F4) . . ┊ . @@ -425,7 +425,7 @@ reply z press F4 ] run [ - event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data ] # check that screen updates the result on the right screen-should-contain [ @@ -444,16 +444,16 @@ scenario run-instruction-manages-screen-per-sandbox [ trace-until 100/app # trace too long assume-screen 100/width, 20/height # left editor is empty - 1:address:array:character <- new [] + 1:address:shared:array:character <- new [] # right editor contains an instruction - 2:address:array:character <- new [print-integer screen, 4] - 3:address:programming-environment-data <- new-programming-environment screen:address:screen, 1:address:array:character, 2:address:array:character + 2:address:shared:array:character <- new [print-integer screen, 4] + 3:address:shared:programming-environment-data <- new-programming-environment screen:address:shared:screen, 1:address:shared:array:character, 2:address:shared:array:character # run the code in the editor assume-console [ press F4 ] run [ - event-loop screen:address:screen, console:address:console, 3:address:programming-environment-data + event-loop screen:address:shared:screen, console:address:shared:console, 3:address:shared:programming-environment-data ] # check that it prints a little toy screen screen-should-contain [ @@ -473,11 +473,11 @@ scenario run-instruction-manages-screen-per-sandbox [ ] ] -recipe editor-contents editor:address:editor-data -> result:address:array:character [ +recipe editor-contents editor:address:shared:editor-data -> result:address:shared:array:character [ local-scope load-ingredients - buf:address:buffer <- new-buffer 80 - curr:address:duplex-list:character <- get *editor, data:offset + buf:address:shared:buffer <- new-buffer 80 + curr:address:shared:duplex-list:character <- get *editor, data:offset # skip § sentinel assert curr, [editor without data is illegal; must have at least a sentinel] curr <- next curr @@ -494,16 +494,16 @@ recipe editor-contents editor:address:editor-data -> result:address:array:charac scenario editor-provides-edited-contents [ assume-screen 10/width, 5/height - 1:address:array:character <- new [abc] - 2:address:editor-data <- new-editor 1:address:array:character, screen:address:screen, 0/left, 10/right + 1:address:shared:array:character <- new [abc] + 2:address:shared:editor-data <- new-editor 1:address:shared:array:character, screen:address:shared:screen, 0/left, 10/right assume-console [ left-click 1, 2 type [def] ] run [ - editor-event-loop screen:address:screen, console:address:console, 2:address:editor-data - 3:address:array:character <- editor-contents 2:address:editor-data - 4:array:character <- copy *3:address:array:character + editor-event-loop screen:address:shared:screen, console:address:shared:console, 2:address:shared:editor-data + 3:address:shared:array:character <- editor-contents 2:address:shared:editor-data + 4:array:character <- copy *3:address:shared:array:character ] memory-should-contain [ 4:array:character <- [abdefc] |