Compare commits

..

212 Commits

Author SHA1 Message Date
Torsten Ruger
14297baeeb update for rubyx integer and api changes 2019-02-09 13:14:01 +02:00
Torsten Ruger
dbb400ac08 fix left view updates 2018-11-06 10:45:15 -08:00
Torsten Ruger
2159c86a5b small fix, works again
update to compiler api changes
some gemfile updates
2018-11-05 18:09:32 -08:00
Torsten Ruger
bba8f787d5 update for yielding
wip
2018-07-30 17:17:27 +03:00
Torsten Ruger
11cdb5872a adjust to rubyx layers
no global machine and positions
also small layout changes
2018-07-03 19:16:12 +03:00
Torsten Ruger
24961e2e10 removed logger (now in util) 2018-06-22 21:48:10 +03:00
Torsten Ruger
3451b546c3 update to work with positions 2018-06-22 19:44:50 +03:00
Torsten Ruger
9832c8730b still +1 errors
also bigger risc view
2018-05-15 12:07:52 +03:00
Torsten Ruger
89e221c748 a larger while example
need a way to see the code
2018-04-20 19:40:17 +03:00
Torsten Ruger
315be69851 fix vool method updating
a start, should do code too
2018-04-18 20:09:22 +03:00
Torsten Ruger
e90597c332 remove fixed height 2018-04-18 17:58:28 +03:00
Torsten Ruger
c379d0f09f also make menu use percentages
somewhat responsive now
even it wont look good small
2018-04-18 17:54:58 +03:00
Torsten Ruger
6c597bea69 remove susy and just use percentage for layout 2018-04-18 17:54:18 +03:00
Torsten Ruger
07edd4ba60 fix mom view update logic 2018-04-17 20:25:56 +03:00
Torsten Ruger
e193d50efd fix classes, status wasn't updating 2018-04-17 19:20:31 +03:00
Torsten Ruger
ce0bdc46a9 introducing mom view
rename source to vool
and instruction to risc
2018-04-17 19:08:10 +03:00
Torsten Ruger
88e49afb60 puts status in header 2018-04-17 18:49:00 +03:00
Torsten Ruger
ff3990841b update space when on re init 2018-04-17 16:43:25 +03:00
Torsten Ruger
0ff418a98c fix startup 2018-04-17 16:35:42 +03:00
Torsten Ruger
7a8e308665 dump dead code
some volt stuff still lying around
2018-04-17 16:35:32 +03:00
Torsten Ruger
2e3475e040 style to fit into site 2018-04-16 21:23:29 +03:00
Torsten Ruger
4ce6aab51c fix spaces z index 2018-04-09 15:10:17 +03:00
Torsten Ruger
17a49348db hack exception
but hey, it can do maths!
2018-04-09 15:08:56 +03:00
Torsten Ruger
73643e4882 add space to left view
show integer and word values
2018-04-07 19:44:47 +03:00
Torsten Ruger
509aff9552 show source better
still wip
2018-04-06 13:03:39 +03:00
Torsten Ruger
4c342d064d make status smaller, source bigger
and value bold
2018-04-04 17:14:33 +03:00
Torsten Ruger
7a9e10fb5f 5 registers per row for better view 2018-04-04 13:16:59 +03:00
Torsten Ruger
c2d69c767c hello world runs through
slower it seems
and source view doesn’t work yet
2018-04-03 19:35:25 +03:00
Torsten Ruger
2feb287b50 slow first steps, 6 before exceptions 2018-04-03 18:24:57 +03:00
Torsten Ruger
0c2738cdef still sputters, but starts again after all that renaming 2018-04-03 16:48:45 +03:00
Torsten Ruger
7be8e040bb add code options
this time inline (not server generated) into the switch view
2016-12-27 20:31:41 +02:00
Torsten Ruger
a6c63f4e57 small layout changes 2016-12-27 18:37:18 +02:00
Torsten Ruger
cc6a050250 getting basics to work 2016-12-25 17:49:09 +02:00
Torsten Ruger
0aafeeeb22 update to use s-tree, not soml 2016-12-22 21:18:51 +02:00
Torsten Ruger
ba34c510c3 update gems, remove older unused stuff 2016-12-22 21:18:10 +02:00
Torsten Ruger
daa75719cc update salaam and fix 2015-11-24 16:26:49 +02:00
Torsten Ruger
5aebc464e2 salaam update and minors 2015-11-10 19:46:21 +02:00
Torsten Ruger
66e989f066 update salama
with word fixes mostly
2015-11-10 11:50:56 +02:00
Torsten Ruger
0a67fc38e4 add missing fie_access to html converter 2015-11-10 11:50:28 +02:00
Torsten Ruger
dee9eb4dca a version of code points
strings and encodings are definitely not the same for mir and opal
the code point version works for me with utf16 encoding (on my machine?)
utf16 is sensible choice though may go with it
2015-11-09 00:04:31 +02:00
Torsten Ruger
7c18ab3e36 update salaam and boot parfait codes too 2015-11-09 00:02:23 +02:00
Torsten Ruger
10664ef090 start on puti 2015-11-09 00:02:02 +02:00
Torsten Ruger
3681b4b5d7 load parfait code over the net too
some very painful promise debugging solved weird string issue
2015-11-09 00:01:44 +02:00
Torsten Ruger
0f7fb9e70f update salaam, fake bignum
Since the interpreter is fixed and uses lignum, some solution
for opal is needed.  Currently hacked
2015-11-08 15:46:25 +02:00
Torsten Ruger
6812b7503b salaam update and small fixes because if that 2015-11-07 22:27:27 +02:00
Torsten Ruger
1b887c0186 fix (slash) logger 2015-11-07 22:26:59 +02:00
Torsten Ruger
969fa758a1 some renames, make space for new layout test 2015-11-07 22:26:39 +02:00
Torsten Ruger
cad3deab3a add working fibonacci examples, while and recursive
for fibo(10) the difference is 270 vs 6500 instructions, a lot
apparently there are as many calls as the fibs result, i.e. 55, for
recursive
2015-11-05 13:58:59 +02:00
Torsten Ruger
453f7d5b4a update salama
updates opal to beta it seems
2015-11-05 13:56:58 +02:00
Torsten Ruger
919b31ed3d remove rescues, better stracktraces
which is funny, because i added the rescues because i wasn’t getting
traces
something changed, possibly opal
2015-11-05 11:43:23 +02:00
Torsten Ruger
30eed9274e fix to use objects instead of ids 2015-11-04 20:29:09 +02:00
Torsten Ruger
cfc5163fb6 more debugging 2015-11-04 20:28:37 +02:00
Torsten Ruger
9c637243ff add flags to status (to debug branches) 2015-11-04 16:45:33 +02:00
Torsten Ruger
9fbf58bf0f lifted logger
don’t really need it in the debugger, but since it’s now used in salama
the require fails ….
2015-11-04 16:30:54 +02:00
Torsten Ruger
7a86f60c2d while code 2015-11-04 16:13:08 +02:00
Torsten Ruger
f7981dcce5 update salaam for int fix
remove  those half indexes
2015-11-04 16:12:57 +02:00
Torsten Ruger
65e5f39420 move to soml ending, new while example 2015-11-04 16:12:37 +02:00
Torsten Ruger
04c7ab7fee update readme and screenshot 2015-11-04 13:12:14 +02:00
Torsten Ruger
04da6af347 fix converter
field_def name has been upgraded, needs processing
2015-11-04 12:31:27 +02:00
Torsten Ruger
7f6f7ee4fd remove link as it doesn't exist anymore 2015-11-04 12:21:03 +02:00
Torsten Ruger
6bbbef235c show labels correctly 2015-11-04 12:20:44 +02:00
Torsten Ruger
ccf3a37003 go to github version 2015-11-04 12:20:20 +02:00
Torsten Ruger
a167a87b1f extract the converter into own file
and small cleanups
2015-11-01 19:14:31 +02:00
Torsten Ruger
d19e89567f updating on changed method 2015-11-01 18:11:38 +02:00
Torsten Ruger
752310ab0a different speed buttons 2015-11-01 18:11:00 +02:00
Torsten Ruger
f2b14c743d dic an spanifying output 2015-11-01 13:36:00 +02:00
Torsten Ruger
09bfae1a5f turning out complete function as html 2015-11-01 13:03:03 +02:00
Torsten Ruger
feeedf973d show all classes, reduce delay 2015-11-01 00:06:03 +02:00
Torsten Ruger
88aa296356 make class view use ref view
so one can drill into a class like any old object
some work refreshing them (as they change on reboot)
2015-10-29 23:36:04 +02:00
Torsten Ruger
e8b0a38478 remove blocks view (superseded by source) 2015-10-29 23:06:24 +02:00
Torsten Ruger
be76a57fde to html processor for code 2015-10-29 19:10:02 +02:00
Torsten Ruger
1fd78bf602 update salaam 2015-10-29 19:09:39 +02:00
Torsten Ruger
10d21614a9 make it faster 2015-10-29 19:09:13 +02:00
Torsten Ruger
a18bbeebdf add run button , while pressed runs the program 2015-10-29 18:36:42 +02:00
Torsten Ruger
b76fe1645e separate ticker for internal codes 2015-10-29 16:53:46 +02:00
Torsten Ruger
4bf8ac5345 raw source int the source view 2015-10-29 16:49:14 +02:00
Torsten Ruger
3477de8c81 salaam update
fixes (last?) index bug
2015-10-27 20:08:23 +02:00
Torsten Ruger
18cb04240d showing integers correctly 2015-10-27 18:09:50 +02:00
Torsten Ruger
a8a233705d change to same file ending 2015-10-27 18:09:24 +02:00
Torsten Ruger
17fb7fbf74 opal scope problems
opal eval is in object scope it seems
2015-10-27 12:47:17 +02:00
Torsten Ruger
922ec10f93 no more blocks, replace with labels 2015-10-27 12:46:53 +02:00
Torsten Ruger
76a698f028 update salaam 2015-10-27 12:46:39 +02:00
Torsten Ruger
b6bfddf536 remove dead code (no going back anyway) 2015-10-27 12:46:15 +02:00
Torsten Ruger
9cb4a787b2 virtual - register update 2015-10-27 12:44:02 +02:00
Torsten Ruger
8cde7011ef update salaam, catch errors on tick
otherwise those errors were silently ignored,
i guess because they were on a ui thread
2015-10-22 17:09:05 +03:00
Torsten Ruger
feca6cfbee fix argument view 2015-10-22 14:44:37 +03:00
Torsten Ruger
75b358f2bb fix status update 2015-10-22 14:44:12 +03:00
Torsten Ruger
88935db881 update salaam 2015-10-22 14:44:00 +03:00
Torsten Ruger
9fc354d30f new example 2015-10-22 14:43:11 +03:00
Torsten Ruger
91e3a8fc03 bit more space for instructions 2015-10-21 18:37:04 +03:00
Torsten Ruger
b4630fb501 add some simple programs
both failing, finally get some work done here
2015-10-21 15:22:56 +03:00
Torsten Ruger
b4fcf6a711 remove local dependency again 2015-10-21 14:08:44 +03:00
Torsten Ruger
94292bf1ca allow for empty view
and reset view when interpreter restarts
2015-10-21 14:05:18 +03:00
Torsten Ruger
906017d1eb let the user switch the program that runs
simply grab one of a presets
clear views and start interpreter with the parse from server
2015-10-21 14:04:42 +03:00
Torsten Ruger
b8e309b701 don't pre-start interpreter anymore, but allow for switching source 2015-10-21 14:03:56 +03:00
Torsten Ruger
4752732bf8 helper to clear the view 2015-10-21 14:03:23 +03:00
Torsten Ruger
45a2c707da simple server api to return possible programs and their parses
Parsley doesn’t work on opal (though it is pure ruby)
thus have to jump through  (client server) hoops
2015-10-21 14:03:02 +03:00
Torsten Ruger
8eade695a4 start of a code repository 2015-10-21 14:01:46 +03:00
Torsten Ruger
82b78b8825 create view directory for views 2015-10-19 19:56:35 +03:00
Torsten Ruger
37e24cd02a update to new syntax 2015-10-19 19:56:10 +03:00
Torsten Ruger
0db8d87c09 putstring 2015-10-17 10:29:04 +03:00
Torsten Ruger
b8dd2b257c update salama 2015-10-17 10:10:33 +03:00
Torsten Ruger
c87b1f615e updating gems 2015-10-07 15:27:34 +03:00
Torsten Ruger
e48b7f5c7a better documentation 2015-10-07 12:24:02 +03:00
Torsten Ruger
ed5b946a70 fix ast for opal 2015-10-07 12:23:46 +03:00
Torsten Ruger
36e3a8d4cc object in register change fixed 2015-10-04 22:39:02 +03:00
Torsten Ruger
d23a9846e3 switch to sat and load code from file 2015-10-02 20:25:54 +03:00
Torsten Ruger
ab55f64cdf minitest adds itself 2015-08-26 12:23:11 +03:00
Torsten Ruger
3ca4f29ed1 yanked diy branch to master 2015-08-25 12:37:29 +02:00
Torsten Ruger
83b9511df3 small ui changes 2015-08-19 22:24:37 +02:00
Torsten Ruger
719f026d0f reduce object to list and register to show that list
also remove duplication in registercontroller
ready for events
2015-08-19 00:22:08 +02:00
Torsten Ruger
d7e0cd665f working more with id only 2015-08-19 00:08:28 +02:00
Torsten Ruger
ef321dab26 start to unify and test listeners 2015-08-18 23:08:12 +02:00
Torsten Ruger
f942ed719a try to get object recursion going 2015-08-16 10:01:12 +03:00
Torsten Ruger
a779daf205 flatten object args and test level 2015-08-15 11:50:44 +03:00
Torsten Ruger
9837461a86 pull out a section for an object 2015-08-14 22:57:37 +03:00
Torsten Ruger
08fba7129b second and third levels for register view 2015-08-14 20:27:06 +03:00
Torsten Ruger
5583a7a56c getting the levels right in registers 2015-08-14 20:14:00 +03:00
Torsten Ruger
3d2dadbd62 show variables for classes, small layout fix 2015-08-13 19:54:45 +03:00
Torsten Ruger
c6d5824dff make suckerfish look nice 2015-08-13 19:32:03 +03:00
Torsten Ruger
a1f1d9d6a4 back to suckerfish 2015-08-13 18:49:22 +03:00
Torsten Ruger
2b9f16dad4 another level for try out 2015-08-13 17:49:12 +03:00
Torsten Ruger
33ee57e605 menumatic instead of tooltips 2015-08-12 21:09:46 +03:00
Torsten Ruger
7b82ff31dd more and meaningful tooltips 2015-08-10 22:29:49 +03:00
Torsten Ruger
8ed2a03ea9 better multiline tooltip code 2015-08-09 12:57:32 +03:00
Torsten Ruger
0926f1f85f more info 2015-08-09 12:15:22 +03:00
Torsten Ruger
72a2d22215 add simtip, remove css hint 2015-08-09 12:15:05 +03:00
Torsten Ruger
abb22f524b better register contents view 2015-08-08 17:52:24 +03:00
Torsten Ruger
b91fabdd90 testing addition 2015-08-04 21:45:49 +03:00
Torsten Ruger
878ec9aecc forgot parslet 2015-07-31 21:41:11 +03:00
Torsten Ruger
50367abcbb try 2015-07-31 20:42:25 +03:00
Torsten Ruger
64078cc331 update to http git 2015-07-31 20:36:35 +03:00
Torsten Ruger
65d95de885 block and source views seperated 2015-07-31 19:42:34 +03:00
Torsten Ruger
bdfafd17c8 classes view separated out 2015-07-31 19:35:06 +03:00
Torsten Ruger
ab08fcc7c1 cleaning, upgrade last pre 2015-07-31 19:31:02 +03:00
Torsten Ruger
cfc6f09ec1 move the interpreter to the app
too ugly to drag it around everywhere
2015-07-31 18:32:36 +03:00
Torsten Ruger
1728cc1b25 made status into own view 2015-07-31 14:10:55 +03:00
Torsten Ruger
5bd6b3517d made view component out of register view 2015-07-31 11:42:26 +03:00
Torsten Ruger
69e51a1037 update gemfile to github versions 2015-07-30 20:07:27 +03:00
Torsten Ruger
ba8768e374 moved interpreter in salama 2015-07-30 19:23:25 +03:00
Torsten Ruger
33b0260bfb move interpretr to salama 2015-07-30 16:03:59 +03:00
Torsten Ruger
b81c8e69b7 cleanup 2015-07-30 15:18:19 +03:00
Torsten Ruger
eba80177ae minor fixes 2015-07-30 15:05:57 +03:00
Torsten Ruger
9afaeba302 add sources 2015-07-30 15:05:44 +03:00
Torsten Ruger
4c4d90385f add clock and method name 2015-07-30 15:05:22 +03:00
Torsten Ruger
e8a5a20db1 fix register update 2015-07-30 14:00:49 +03:00
Torsten Ruger
08beaa2d93 formatting 2015-07-30 11:26:48 +03:00
Torsten Ruger
bb24a6cae5 adds button and blocks tick over 2015-07-30 10:27:27 +03:00
Torsten Ruger
d8a3657365 some real models 2015-07-30 10:09:04 +03:00
Torsten Ruger
a2f3daa828 registers back (non updating) 2015-07-29 21:05:02 +03:00
Torsten Ruger
9383f0d75e salaam boots and classes are shown 2015-07-29 20:50:39 +03:00
Torsten Ruger
264a52c184 basic view up with styles 2015-07-29 18:50:03 +03:00
Torsten Ruger
3bad4cc570 first steps (nothing works) 2015-07-29 18:19:26 +03:00
Torsten Ruger
56521fd5ed new versions 2015-07-29 17:34:15 +03:00
Torsten Ruger
a0b37977a9 volt new overlay 2015-07-29 17:26:04 +03:00
Torsten Ruger
9c7a333127 move code here 2015-07-29 17:17:37 +03:00
Torsten Ruger
485f3134dd revieve volt scaffold 2015-07-29 17:13:04 +03:00
Torsten Ruger
79383d89b1 trying to get register view to update 2015-07-29 16:39:15 +03:00
Torsten Ruger
933b64c499 better docs, new pic 2015-07-28 16:36:29 +03:00
Torsten Ruger
62e5761a40 using github gems 2015-07-28 16:35:45 +03:00
Torsten Ruger
07f7945917 move to suzy is done 2015-07-28 16:16:33 +03:00
Torsten Ruger
756ab31a61 add status view and fixes 2015-07-28 16:16:09 +03:00
Torsten Ruger
557c455167 switch to susy
a rewire basically, but much clearer
2015-07-27 21:29:41 +03:00
Torsten Ruger
7e34ae003e integrating the sources to views 2015-07-27 12:09:35 +03:00
Torsten Ruger
e460e0041b finishes the yellow world instructions 2015-07-26 18:27:12 +03:00
Torsten Ruger
87cec0f4bc some read me info 2015-07-26 14:38:07 +03:00
Torsten Ruger
1ae4baf3f7 implement put string and fix set 2015-07-26 13:59:58 +03:00
Torsten Ruger
228b1b5832 slight improvement on the register view
still lagging, but …
2015-07-26 13:24:00 +03:00
Torsten Ruger
add84432b4 removed unused 2015-07-26 12:52:29 +03:00
Torsten Ruger
6ce51c38db better view for registers 2015-07-26 12:51:57 +03:00
Torsten Ruger
6ba3c54690 three more instruction for interpreter 2015-07-26 09:04:57 +03:00
Torsten Ruger
3464e50b2f better block view 2015-07-26 09:04:34 +03:00
Torsten Ruger
515e1b106b better register an instruction view 2015-07-25 21:04:20 +03:00
Torsten Ruger
b693f55a29 showing active instruction with bg 2015-07-25 15:28:59 +03:00
Torsten Ruger
2f66bd9f08 Slot instructions and tests 2015-07-24 21:15:47 +03:00
Torsten Ruger
93ac945dd2 first mini test, remove spec 2015-07-24 18:38:37 +03:00
Torsten Ruger
1526656dfe fix register (sym/ref) 2015-07-24 17:21:13 +03:00
Torsten Ruger
959cb628fa implements fetching of next instruction 2015-07-24 15:48:12 +03:00
Torsten Ruger
5d42da9d03 next instruction working
but no clock yet
2015-07-24 13:56:31 +03:00
Torsten Ruger
f5ece67233 first interpreted instruction, with gui change 2015-07-24 10:15:58 +03:00
Torsten Ruger
246bb5ee4f debug off is faster 2015-07-24 10:15:27 +03:00
Torsten Ruger
0cdd5fdf13 registering events with objects not procs
to make unregistering easier
2015-07-24 10:01:01 +03:00
Torsten Ruger
8183dfd6b1 simple events and triggers in interpreter 2015-07-23 20:09:19 +03:00
Torsten Ruger
950c77b127 react update 2015-07-23 20:08:50 +03:00
Torsten Ruger
a896702880 passing the interpreter around 2015-07-23 20:08:40 +03:00
Torsten Ruger
53d576ef90 showing actual block and actual instruction
time to ponder a little more
2015-07-23 17:26:48 +03:00
Torsten Ruger
1f19a28906 trying to find exception 2015-07-23 16:23:10 +03:00
Torsten Ruger
03c0041255 create separate main
figuring load order
2015-07-23 14:59:29 +03:00
Torsten Ruger
736bff02a5 trying to find .name error 2015-07-23 14:59:15 +03:00
Torsten Ruger
2645f54d5b move registers to hash 2015-07-23 13:20:53 +03:00
Torsten Ruger
aa2303ddaa add lib and interpreter skeleton 2015-07-23 13:15:44 +03:00
Torsten Ruger
f4dfbb5845 move to haml style class names 2015-07-23 13:15:26 +03:00
Torsten Ruger
398d364c02 got vm to boot and classes to show 2015-07-22 23:08:36 +03:00
Torsten Ruger
3d96d59371 sort of noop of version is working 2015-07-22 22:05:31 +03:00
Torsten Ruger
a0721a0cde move to opal from sinatra
also external index
2015-07-22 17:10:50 +03:00
Torsten Ruger
d021816726 move sources to app directory 2015-07-22 16:26:46 +03:00
Torsten Ruger
e8d9000a74 file per class 2015-07-22 16:22:54 +03:00
Torsten Ruger
db7fa423bb a noon start, copied from examples 2015-07-22 16:17:25 +03:00
Torsten Ruger
bd882b7d2e remove volt 2015-07-21 20:25:57 +03:00
Torsten Ruger
5c2f423f58 reinstantiating lib dir 2015-07-18 11:25:11 +03:00
Torsten Ruger
19a0b7f9fe get vm source on screen 2015-07-18 11:22:42 +03:00
Torsten Ruger
4305ddaf1d copied salama in for reload
but have to rethink approach
2015-07-17 22:44:20 +03:00
Torsten Ruger
b5b0630060 rename 2015-07-17 19:27:46 +03:00
Torsten Ruger
c22a4a95d3 add block inspect, status: up to first jump 2015-07-17 15:14:41 +03:00
Torsten Ruger
69414a11f9 fix eval by including parser 2015-07-17 11:42:21 +03:00
Torsten Ruger
40d97dcf87 remove double boot 2015-07-17 11:41:59 +03:00
Torsten Ruger
acd66f66f3 add hint.css for tooltips 2015-07-17 11:37:02 +03:00
Torsten Ruger
f2af076c8e small view change 2015-07-16 17:35:19 +03:00
Torsten Ruger
1efce561d7 basic html skeleton, classes and registers 2015-07-16 10:43:49 +03:00
Torsten Ruger
1d005862ac remove pixi, going back to html 2015-07-15 19:26:11 +03:00
Torsten Ruger
e51d6cb3fa remove hardcoded size and move point code to pixie 2015-07-14 19:59:21 +03:00
Torsten Ruger
d47d8a9e2a still playing luke, has the direction wrong 2015-07-14 16:57:44 +03:00
48 changed files with 1187 additions and 681 deletions

47
.gitignore vendored
View File

@ -1,42 +1,9 @@
# database
db
# rdoc generated
rdoc
# yard generated
doc
.yardoc
# bundler
.bundle
*.gem
# jeweler generated
pkg
#
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
#
# For MacOS:
#
.config
.yardoc
tmp
.idea
.yardoc
.sass-cache
.DS_Store
# For TextMate
#*.tmproj
#tmtags
# For emacs:
#*~
#\#*
#.\#*
# For vim:
#*.swp
# Object files
*.o
log
tmp/
compiled

25
Gemfile
View File

@ -1,24 +1,21 @@
source 'https://rubygems.org'
gem "opal" , :github => "opal/opal"
gem "opal"
gem 'opal-sprockets'
gem 'opal-browser'
#gem "salama" , "0.2" , :path => "../salama"
gem "rubyx" , "0.6" , path: "../rubyx"
gem "rx-file" , :git => "https://github.com/ruby-x/rx-file"
gem "parslet" , github: "salama/parslet"
gem "salama" , github: "salama/salama"
gem "salama-reader" , github: "salama/salama-reader"
gem "salama-arm" , github: "salama/salama-arm"
gem "salama-object-file" , github: "salama/salama-object-file"
gem "sass"
gem "susy"
group :test do
# Testing dependencies
gem 'rspec', '~> 3.2.0'
gem 'opal-rspec', '~> 0.4.2'
gem 'capybara', '~> 2.4.2'
gem 'selenium-webdriver', '~> 2.43.0'
gem 'chromedriver2-helper', '~> 0.0.8'
gem 'poltergeist', '~> 1.5.0'
gem "minitest"
gem 'rspec'
gem 'capybara'
gem 'selenium-webdriver'
gem 'chromedriver2-helper'
gem 'poltergeist'
end

View File

@ -1,134 +1,120 @@
GIT
remote: git://github.com/opal/opal.git
revision: c604685071f8560d3357044683a99b80b210a99b
remote: https://github.com/ruby-x/rx-file
revision: 7c4a5546136d1bad065803da91778b209c18cb4d
specs:
opal (0.9.0.dev)
hike (~> 1.2)
sourcemap (~> 0.1.0)
sprockets (~> 3.1)
tilt (>= 1.4)
rx-file (0.3.0)
GIT
remote: git://github.com/salama/parslet.git
revision: b8bf8db20a242eb6bd8fec88027e3b2ae19276e8
PATH
remote: ../rubyx
specs:
parslet (1.7.0)
GIT
remote: git://github.com/salama/salama-arm.git
revision: 0bd5091e3f284ecf040e0086a41d2449cd5afb7a
specs:
salama-arm (0.0.1)
GIT
remote: git://github.com/salama/salama-object-file.git
revision: fbae6a02764dbe97e01e4833f9ffffe09879b100
specs:
salama-object-file (0.2.0)
GIT
remote: git://github.com/salama/salama-reader.git
revision: 841592c667acea1e796f950851262e6938b231bc
specs:
salama-reader (0.2.0)
parslet (~> 1.7.0)
GIT
remote: git://github.com/salama/salama.git
revision: df95b8b54de103523743cbfd5c46d87af84c6b09
specs:
salama (0.2.0)
salama-object-file (~> 0.2)
salama-reader (~> 0.2)
rubyx (0.6.0)
parser (~> 2.3.0)
rx-file (~> 0.3)
GEM
remote: https://rubygems.org/
specs:
capybara (2.4.4)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
childprocess (0.5.6)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
ast (2.4.0)
capybara (3.13.2)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (~> 1.2)
xpath (~> 3.2)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
chromedriver2-helper (0.0.8)
chromedriver2-helper (0.0.10)
nokogiri
cliver (0.3.2)
diff-lcs (1.2.5)
ffi (1.9.10)
concurrent-ruby (1.1.4)
diff-lcs (1.3)
ffi (1.10.0)
hike (1.2.3)
mime-types (2.6.1)
mini_portile (0.6.2)
multi_json (1.11.2)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
mini_mime (1.0.1)
mini_portile2 (2.4.0)
minitest (5.11.3)
nokogiri (1.10.1)
mini_portile2 (~> 2.4.0)
opal (0.11.4)
ast (>= 2.3.0)
hike (~> 1.2)
parser (= 2.3.3.1)
sourcemap (~> 0.1.0)
opal-browser (0.2.0)
opal
paggio
opal-rspec (0.4.3)
opal (>= 0.7.0, < 0.9)
paggio (0.2.4)
poltergeist (1.5.1)
capybara (~> 2.1)
opal-sprockets (0.4.2.0.11.0.3.1)
opal (~> 0.11.0)
sprockets (~> 3.1)
tilt (>= 1.4)
paggio (0.2.6)
parser (2.3.3.1)
ast (~> 2.2)
poltergeist (1.18.1)
capybara (>= 2.1, < 4)
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
rack (1.6.4)
rack-test (0.6.3)
rack (>= 1.0)
rspec (3.2.0)
rspec-core (~> 3.2.0)
rspec-expectations (~> 3.2.0)
rspec-mocks (~> 3.2.0)
rspec-core (3.2.3)
rspec-support (~> 3.2.0)
rspec-expectations (3.2.1)
public_suffix (3.0.3)
rack (2.0.6)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
regexp_parser (1.3.0)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-mocks (3.2.1)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
rubyzip (1.1.7)
sass (3.4.16)
selenium-webdriver (2.43.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
rubyzip (1.2.2)
sass (3.7.3)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
selenium-webdriver (3.141.0)
childprocess (~> 0.5)
multi_json (~> 1.0)
rubyzip (~> 1.0)
websocket (~> 1.0)
rubyzip (~> 1.2, >= 1.2.2)
sourcemap (0.1.1)
sprockets (3.3.2)
rack (~> 1.0)
susy (2.2.5)
sass (>= 3.3.0, < 3.5)
tilt (2.0.1)
websocket (1.2.2)
websocket-driver (0.5.4)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
tilt (2.0.9)
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
xpath (2.0.0)
nokogiri (~> 1.3)
websocket-extensions (0.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
PLATFORMS
ruby
DEPENDENCIES
capybara (~> 2.4.2)
chromedriver2-helper (~> 0.0.8)
opal!
capybara
chromedriver2-helper
minitest
opal
opal-browser
opal-rspec (~> 0.4.2)
parslet!
poltergeist (~> 1.5.0)
rspec (~> 3.2.0)
salama!
salama-arm!
salama-object-file!
salama-reader!
opal-sprockets
poltergeist
rspec
rubyx (= 0.6)!
rx-file!
sass
selenium-webdriver (~> 2.43.0)
susy
selenium-webdriver
BUNDLED WITH
1.10.5
1.17.2

128
README.md
View File

@ -1,23 +1,117 @@
### statement of intent
just starting and not quite sure, but here is the direction
# Debugger
I don't want to use gdb anymore, and it would be easier without using the qemu setup, so:
After some tryouts it ended up being an Opal application. That is ruby as javascript in the browser.
Below is a screenshot.
- single step debugging of the register machine level (as close to arm as need be)
- visual transitions for steps
- visualisation of data in registers (some kind of link to the object)
- show the current instruction and a few around
- show vm object (message etc)
- show effect of register transitions on vm objects
- visualize vm object content (again some links)
![Debugger](https://raw.githubusercontent.com/rubyx/rubyx-debugger/master/static/debugger.png)
## Views
From left to right there are several views showing different data and controls.
All of the green boxes are in fact pop-up menus and can show more information.
Most of these are implemented as a single class with the name reflecting what part.
I wrote 2 base classes that handle element generation (ie there is hardly any html involved, just elements)
### Switch view
Top left at the top is a little control to switch files.
The files need to be in the repository, but at least one can have several and switch between
them without stopping the debugger.
Parsing is the only thing that opal chokes on, so the files are parsed by a server script and the
ast is sent to the browser.
### Classes View
The first column on the left is a list of classes in the system. Like on all boxes one can hover
over a name to look at the class and it's instance variables (recursively)
# Space
### Source View
- Visualise the object space in some way
- Visualise single object, bit like atoms
- values immediate
- objects as link
Next is a view of the Soml source. The Source is reconstructed from the ast as html.
Soml (Salama object machine language) is is a statically typed language,
maybe in spirit close to c++ (without the c). In the future Salama will compile ruby to soml.
While stepping through the code, those parts of the code that are active get highlighted in blue.
Currently stepping is done only in register instructions, which means that depending on the source
constructs it may take many steps for the cursor to move on.
Each step will show progress on the register level though (next view)
### Register Instruction view
Salama defines a register machine level which is quite close to the arm machine, but with more
sensible names. It has 16 registers (below) and an instruction set that is useful for Soml.
Data movement related instruction implement an indexed get and set. There is also Constant load and
integer operators and off course branches.
Instructions print their name and used registers r0-r15.
The next instruction to be executed is highlighted in blue. A list of previous instructions is shown.
One can follow the effect of instruction in the register view below.
### Status View
The last view at the top right show the status of the machine (interpreter to be precise), the
instruction count and any stdout
Current controls include stepping and three speeds of running the program.
- Next (green button) will execute exactly one instruction when clicked. Mostly useful when
debugging the compiler, ie inspecting the generated code.
- Crawl (first blue button) will execute at a moderate speed. One can still follow the
logic at the register level
- Run (second blue button) runs the program at a higher speed where register instruction just
whizz by, but one can still follow the source view. Mainly used to verify that the source executes
as expected and also to get to a specific place in the program (in the absence of breakpoints)
- Wizz (third blue button) makes the program run so fast that it's only useful function is to
fast forward in the code (while debugging)
### Register view
The bottom part of the screen is taken up by the 16 register. As we execute an object oriented
language, we show the object contents if it is an object (not an integer) in a register.
The (virtual) machine only uses objects, and specifically a linked list of Message objects to
make calls. The current message is always in register 0 (analgous to a stack pointer).
All other registers are scratch for statement use.
In Soml expressions compile to the register that holds the expressions value and statements may use
all registers and may not rely on anything other than the message in register 0.
The Register view is now greatly improved, especially in it's dynamic features:
- when the contents update the register obviously updates
- when the object that the register holds updates, the new value is shown immediately
- hovering over a variable will **expand that variable** .
- the hovering works recursively, so it is possible to drill down into objects for several levels
The last feature of inspecting objects is show in the screenshot. This makes it possible
to very quickly verify the programs behaviour. As it is a pure object system , all data is in
objects, and all objects can be inspected.
### Debugging the debugger
Opal is pre 1.0 and is a wip. While current source map support is quite good, one only gets
real lines when switching debug on. Debug make it load every single file seperately, slooows it
down in other words. Set DEBUG environment to switch it on.
I set the sprockets cache to mem-cache and that increase load time from 12s to 1 , so it's quite
usable and restarting a debug is fine.
## Todos
Breakpoints would be nice at some point. Both in step count and variable value.
## Trying it out
Clone
Bundle
bundle exec rackup

98
assets/css/app.css.sass Normal file
View File

@ -0,0 +1,98 @@
body
background-color: #1a1a1a
color: white
.one_class, .classes, .vool_view ,.mom_view , .risc_view, .status_view ,.vool_view
position: relative
float: left
.mom_view , .risc_view , .status_view , .registers_view, .register_view
position: relative
float: left
.one_class
margin: 10px
.classes
width: 16%
margin-left: 1%
.vool_view
width: 12%
margin-left: 1%
.mom_view
width: 16%
margin-left: 1%
overflow-x: hidden
.risc_view
width: 34%
margin-left: 1%
overflow-x: hidden
.status_view
width: 14%
margin-left: 1%
line-height : 1.25em
.header_state
color: #53a5ff
.labels_view
width: 18%
margin-right: 2%
height: 200px
.registers_view
width: 79%
margin-left: 1%
.register_view
width: 19%
margin-right: 1%
margin-top: 10px
&:nth-child(5n + 1)
clear: left
.field
width: 80%
.value
width: 80%
.value_head
background-color: #C5FFD9
.statement
margin-left: 10px
.ticker
text-align: right
.next , .run , .wizz
border-radius: 7px
font-size: 1em
.next
background-color: #00FF66
.run
background-color: #00CC33
.wizz
background-color: #009900
.risc_bright , .mom_bright
background-color: black
color: #53a5ff
border-radius: 7px
.fade_in
transition: background-color 100ms linear
padding-right: 6px
padding-left: 6px
background-color: #00E3FF
border-radius: 7px
h4.select
z-index: 20

View File

@ -1,71 +0,0 @@
// Place your apps css here
@import "susy";
$susy: (
columns: 24 ,
gutter-position: split ,
);
.debugger_view { @include container(90%); }
.classes {
@include span(3);
}
.one_class {
margin: 10px;
}
.file_view {
@include span(4);
margin-left: span(1);
}
.source_view { @include span(6); }
.block_view {
@include span(4);
margin-right: span(2);
height: 200px;
}
.status_view {
@include span(2 at 22);
line-height : 1.25em;
}
.registers_view {
@include span(20 at 3);
}
.register_view {
@include gallery(4);
margin-top: 10px;
}
.field {
@include span(5)
}
.value {
@include span(18)
}
.value_head {
background-color: #C5FFD9;
}
.act{
background-color: #00B3FF;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
font-size: 100%;
}
.bright {
padding-right: 6px;
padding-left: 6px;
background-color: #00E3FF ;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
}

45
assets/css/menu.css.sass Normal file
View File

@ -0,0 +1,45 @@
body
font-family: arial, helvetica, serif
#nav , #nav ul
padding: 0
margin: 0
list-style: none
float: left
width: 100%
border-radius: 8px
background: black
border: 2px solid #C3D46A
#nav
li
position: relative
float: left
line-height: 1.25em
width: 99%
a , span
width: 99%
display: block
text-decoration: none
background-color: black
border-radius: 7px
ul
position: absolute
left: -999em
margin-left: 99%
margin-top: -2.7em
ul
left: -999em
#nav li a:hover
color: white
background-color: #98CC1F
#nav li:hover ul ul, #nav li:hover ul ul ul , #nav li:hover ul ul ul ul , #nav li:hover ul ul ul ul ul
left: -999em
/* lists nested under hovered list items */
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul , #nav li li li li li:hover ul
left: auto

View File

@ -1,60 +0,0 @@
body {
font-family: arial, helvetica, serif;
}
#nav, #nav ul { /* all lists */
padding: 0;
margin: 0;
list-style: none;
float : left;
width : 10em;
/*border around submenu goes here*/
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
background:#fff;
border:1px solid #C3D46A
}
#nav li { /* all list items */
position : relative;
float : left;
line-height : 1.25em;
width: 9em;
}
#nav li ul { /* second-level lists */
position : absolute;
left: -999em;
margin-left : 10.0em;
margin-top : -2.7em;
}
#nav li ul ul { /* third-and-above-level lists */
left: -999em;
}
#nav li a , li span {
padding-left: 0.5em;
width : 9.5em;
display : block;
color : black;
font-weight : bold;
text-decoration : none;
background-color : white;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
}
#nav li a:hover {
color : white;
background-color : #98CC1F;
}
#nav li:hover ul ul, #nav li:hover ul ul ul , #nav li:hover ul ul ul ul , #nav li:hover ul ul ul ul ul{
left: -999em;
}
/* lists nested under hovered list items */
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul , #nav li li li li li:hover ul {
left: auto;
}

5
codes/a_puti.soml Normal file
View File

@ -0,0 +1,5 @@
class Object
int main()
return 55.puti()
end
end

22
codes/fibo_recur.soml Normal file
View File

@ -0,0 +1,22 @@
class Object
int fibonaccir( int n )
if_plus( n - 1 )
int tmp
tmp = n - 1
int a = fibonaccir( tmp )
tmp = n - 2
int b = fibonaccir( tmp )
return a + b
else
return n
end
end
int fib_print(int n)
int fib = fibonaccir( n )
fib.putint()
return fib
end
int main()
return fib_print(7)
end
end

20
codes/fibo_while.soml Normal file
View File

@ -0,0 +1,20 @@
class Object
int fibonaccit(int n)
int a = 0
int b = 1
n = n - 1
while_plus( n )
int tmp = a
a = b
b = tmp + b
n = n - 1
end
b.putint()
return b
end
int main()
int f = fibonaccit( 10 )
return f.puti()
end
end

6
codes/hello_world.soml Normal file
View File

@ -0,0 +1,6 @@
class Object
int main()
"Hello World".putstring()
return 1
end
end

13
codes/if_called.soml Normal file
View File

@ -0,0 +1,13 @@
class Object
int itest(int n)
if_zero( n - 12)
"then".putstring()
else
"else".putstring()
end
end
int main()
itest(20)
end
end

10
codes/if_else.soml Normal file
View File

@ -0,0 +1,10 @@
class Object
int main()
int n = 14
if_plus( n - 12)
"then".putstring()
else
"else".putstring()
end
end
end

23
codes/layout.soml Normal file
View File

@ -0,0 +1,23 @@
class Layout < Object
Class object_class()
return get_internal_word(2)
end
end
class Object
Layout get_layout()
return get_internal_word(1)
end
Class get_class()
Layout l = get_layout()
return l.object_class()
end
int main()
return get_class()
end
end

8
codes/offset_check.soml Normal file
View File

@ -0,0 +1,8 @@
class Object
int puts(Word str)
return str
end
int main()
puts("Hello")
end
end

23
codes/times.soml Normal file
View File

@ -0,0 +1,23 @@
class Object
int times(int a, int b)
if_zero( b )
a = 0
else
int m = b - 1
int t = times(a, m)
a = a + t
end
return a
end
int t_seven()
int tim = times(5,3)
tim.putint()
return tim
end
int main()
return t_seven()
end
end

12
codes/while.soml Normal file
View File

@ -0,0 +1,12 @@
class Object
int main()
int i = 5
while_plus(i)
"out ".putstring()
i = i - 1
end
return i
end
end

View File

@ -1,31 +1,16 @@
require 'bundler'
Bundler.require
require 'tilt/erb'
require_relative "lib/parse_task"
require "opal"
require 'opal-browser'
require 'opal-sprockets'
Opal.use_gem("salama")
Opal.use_gem("salama-arm")
Opal.use_gem("rubyx")
class DebugServer < Opal::Server
def call(env)
if( env["REQUEST_PATH"] == "/tasks.json")
[200, { 'Content-Type' => 'text/json' }, [ParseTask.new.parse(1).to_json]]
else
super(env)
end
end
end
run DebugServer.new { |s|
s.main = 'debugger'
run Opal::Sprockets::Server.new { |s|
s.main = 'debugger.js.rb'
s.append_path 'lib'
s.append_path 'assets'
# s.source_map = true
s.debug = !ENV["DEBUG"].nil?
s.index_path = "index.html.erb"
s.sprockets.cache = Sprockets::Cache::MemoryStore.new(5000)
s.sprockets.cache = Sprockets::Cache::MemoryStore.new(50000)
}

View File

@ -2,6 +2,7 @@
<html>
<head>
<title>Debugger</title>
<meta charset="utf-8"/>
<link rel="stylesheet" href="/assets/css/menu.css" type="text/css" charset="utf-8">
<link rel="stylesheet" href="/assets/css/app.css" type="text/css" charset="utf-8">
</head>

View File

@ -1,12 +1,17 @@
require_relative "element_view"
# A very simple ElementView with constant text and class. It uses the ElementView.div function
# to generate the html, see there for details
#
class ConstantView < ElementView
# store the class and text
def initialize class_or_id , text = nil
@class_or_id = class_or_id
@text = text
end
# use ElementView.div to create html from the class and text
def draw
@element = div(@class_or_id , @text)
end

View File

@ -1,3 +1,12 @@
# The basic idea is somewhat that of a shadow dom.
#
# ElementView wraps a single div with whatever content you want (derive to implement the view)
#
# It must have an element, which is drawn. Draw returns the div or whatever. An ElementView
# does not draw itself, but rather is drawn.
#
# Listviews provide structure
#
class ElementView
def initialize
@ -18,7 +27,7 @@ class ElementView
# second argument is optional, but if given will be added as text (content) to the newly
# created Element
# return the new Element, which is not linked into the dom at that point (see << and add*)
def div name_class = "div" , text = nil
def div(name_class = "div" , text = nil)
name , clazz = name_class.split(".")
name = "div" if name.empty?
element = $document.create_element(name)
@ -49,8 +58,8 @@ class ElementView
@element = wrap_node_with @element , wrapper
end
#wrap the given node with the wappper, so for a div wrapper and a button node
# the result will be <div> <button>hwatever was in there</button> <div>
# wrap the given node with the wappper, so for a div wrapper and a button node
# the result will be <div> <button>whatever was in there</button> <div>
def wrap_node_with node , wrapper
node.replace_with(wrapper) if node.parent
wrapper << node

View File

@ -1,5 +1,14 @@
require_relative "element_view"
# Listviews hold an array of elements and are responsible for drawing (and re-drawing them)
#
# A ListView hold the elements, but also the drawn html divs. You can change the element
# structure by adding/removing/replacing and the ListView will take care of redrawing the html
#
# A ListView is itself an ElementView so one can build recursive structures.
#
# Also one can easily change the root html element, or by deriving wrap or edit the resulting html
#
class ListView < ElementView
def initialize children
@ -7,6 +16,10 @@ class ListView < ElementView
@elements = []
end
def length
@children.length
end
# create a root node acording to the tag given (default div)
# The tag name will be passed to the div function, so class and id may be set as well (see there)
# draw all children and keep the elements as @elements
@ -21,13 +34,13 @@ class ListView < ElementView
# replace the child at index with the given one (second arg)
# The child must be an ElementView , which will be rendered and
# the old node will be replaces in the live dom
def replace_at index , with
# the old node will be replaced in the live dom
def replace_at( index , node)
old = @elements[index]
@children[index] = with
rendered = with.draw
@children[index] = node
rendered = node.draw
@elements[index] = rendered
old.replace_with rendered
old.replace_with(rendered) if old
end
# remove the first child and element (from view)
@ -37,10 +50,15 @@ class ListView < ElementView
# remove both child and element at given position
def remove_at index
raise "insex out of bounds #{index} => #{@children.length}" if(index >= @children.length or index < 0)
raise "index out of bounds #{index} => #{@children.length}" if(index >= @children.length or index < 0)
@children.delete_at( index )
element = @elements.delete_at(index)
element.remove
element.remove if element
end
# remove all elements and views, basically resetting the list to empty
def clear_view
remove_first while( ! @children.empty? )
end
# append a View instnace to the children array

View File

@ -1,58 +0,0 @@
class BlocksView < ListView
def initialize interpreter
@interpreter = interpreter
@interpreter.register_event(:instruction_changed, self)
super([BlockView.new(@interpreter.block)])
@method_name = method_name
end
def draw
super()
wrap_element div("div.block_view") << div("h4" , "Method + Block " ) << div("h4.method" , @method_name)
return @element
end
def instruction_changed
new_name = method_name
unless new_name == @method_name
@method_name = new_name
@element.at_css(".method").text = method_name
end
return if @interpreter.block.object_id == @children.last.block.object_id
@elements.last.at_css(".bright").remove_class("bright")
append_view( BlockView.new(@interpreter.block) )
remove_first if( @elements.length > 6)
end
def method_name
bl = @interpreter.block
return "" unless bl
return bl.method if bl.method.is_a? String
"#{bl.method.for_class.name}.#{bl.method.name}"
end
end
class BlockView < ElementView
def initialize block
@block = block
end
attr_reader :block
def draw
@element = div("div") << div("span.bright" , block_name )
end
def method_name
return @block.method if @block.method.is_a? String
@block.method.name
end
def block_name
return @block if @block.is_a? String
"#{method_name}.#{@block.name}"
end
end

View File

@ -1,37 +0,0 @@
class ClassesView < ListView
def initialize interpreter
@interpreter = interpreter
classes = []
Virtual.machine.space.classes.each do |name , claz|
next if [:Kernel,:Module,:MetaClass,:BinaryCode].index name
classes << claz
end
classes.sort! {|a,b| a.name <=> b.name }
super( classes.collect{|c| ClassView.new(c)})
end
def draw
super()
wrap_element div("ul.nav!")
wrap_element( div(".classes") << div("h4" , "Classes") )
return @element
end
end
class ClassView < ElementView
def initialize clazz
@clazz = clazz
end
def draw
@element = div("li") << div( "a" , @clazz.name ) << (ul = div("ul"))
@clazz.object_layout.object_instance_names.each do |name|
ul << (div("li") << div("a", name ))
end
@element.style["z-index"] = 20
@element
end
end

62
lib/debugger.js.rb Normal file
View File

@ -0,0 +1,62 @@
require "opal"
require "opal-parser"
require 'opal/compiler'
require 'browser'
require 'browser/http'
require 'native'
require "rubyx"
require "ast"
require "util/eventable"
require "risc/interpreter"
# the base, our own mini framework, allows for child and parent views and handles updates
require "base/list_view"
# each seperate view is in it's own class.
require "views/left_view"
require "views/status_view"
require "views/vool_view"
require "views/mom_view"
require "views/risc_view"
require "views/registers_view"
class Bignum
end
class String
def codepoints
arr = []
one = nil
self.each_byte do |c|
if( one )
arr << (one + c * 256)
one = nil
else
one = c
end
end
arr
end
end
module RubyX
def self.debugger_options
{ parfait: {factory: 50} }
end
end
class MainView < ListView
def initialize
compiler = RubyX::RubyXCompiler.new(RubyX.debugger_options)
input = "class Space;def main(arg); return 1; end; end"
linker = compiler.ruby_to_binary(input , :interpreter)
@interpreter = Risc::Interpreter.new(linker)
super( [LeftView.new(@interpreter) ,
VoolView.new(@interpreter) ,
MomView.new(@interpreter) ,
RiscView.new(@interpreter) ,
StatusView.new(@interpreter) ,
RegistersView.new(@interpreter) ] )
end
end
view = MainView.new()
view.draw.append_to($document.body)

View File

@ -1,47 +0,0 @@
require "opal"
require "opal-parser"
require 'browser'
require 'native'
require "salama"
require "interpreter/interpreter"
require "base/list_view"
require_relative "classes_view"
require_relative "status_view"
require_relative "file_view"
require_relative "blocks_view"
require_relative "instruction_view"
require_relative "registers_view"
class MainView < ListView
def initialize
machine = Virtual.machine.boot
# compile_main includes the parse
# parsing generates an ast as seen below and then compiles it.
# machine.compile_main "2 + 5"
# so the code above is functionally equivalent to the one below, minus the parse
# When the ast expression is given all works, so pretty sure it is the parse that fails
code = Ast::OperatorExpression.new("+", Ast::IntegerExpression.new(2),Ast::IntegerExpression.new(5))
Virtual::Compiler.compile( code , machine.space.get_main )
machine.run_before "Register::CallImplementation"
@interpreter = Interpreter::Interpreter.new
@interpreter.start machine.init
super( [ClassesView.new(@interpreter) ,
FileView.new ,
BlocksView.new(@interpreter) ,
InstructionView.new(@interpreter) ,
StatusView.new(@interpreter) ,
RegistersView.new(@interpreter) ] )
end
end
view = MainView.new()
view.draw.append_to($document.body)

View File

@ -1,8 +0,0 @@
class FileView < ElementView
def draw
@element = div(".file_view") << div("h4" ,"Future")
end
end

View File

@ -1,30 +0,0 @@
require "base/constant_view"
require "base/list_view"
class InstructionView < ListView
def initialize interpreter
@interpreter = interpreter
super([ConstantView.new( "span.bright" , "starting" )])
@interpreter.register_event(:instruction_changed, self)
end
def instruction_changed
@element.at_css(".bright").remove_class("bright")
instruction = append_view( ConstantView.new( "span.bright" , instruction_text ) )
wrap_node_with instruction , div
remove_first if( @elements.length > 6)
end
def draw
super()
wrap_node_with @elements.first , div
wrap_element div(".source_view") << div("h4" ,"Virtual Machine Instruction")
@element
end
def instruction_text
return "" unless @interpreter.instruction
@interpreter.instruction.to_s
end
end

View File

@ -1,54 +0,0 @@
require_relative "ref_view"
class ObjectView < ListView
def initialize object_id , interpreter = nil , z = nil
@object_id = object_id
@z = z
@interpreter = interpreter
@interpreter.register_event(:object_changed, self) if interpreter
super( content_elements )
end
def draw
@element = super(@interpreter ? "ul.nav!" : "ul")
prepend_element div("li" , "-------------------------")
prepend_element div( "li" ) << div("span" , class_header(@object_id) )
return @element
end
def object_changed reg , at
puts "Object changed in #{reg}"
for_object = @interpreter.get_register( reg )
return unless for_object == @object_id
puts "Object changed #{for_object} , at #{at}"
end
def class_header(id)
object = Virtual.machine.objects[id]
clazz = object.class.name.split("::").last
[clazz, id].join " : "
end
def content_elements
object = Virtual.machine.objects[@object_id]
fields = []
if object and ! object.is_a?(String)
fields << RefView.new( "layout" , object.get_layout.object_id , @z )
object.get_instance_variables.each do |variable|
f = object.get_instance_variable(variable)
fields << RefView.new( variable , f.object_id , @z )
end
if( object.is_a?(Parfait::List) )
index = 1
object.each do | o , i|
fields << RefView.new( index.to_s , o.object_id , @z )
index += 1
end
end
end
fields
end
end

View File

@ -1,11 +0,0 @@
require "salama-reader"
class ParseTask
def parse(num)
string_input = '"Hello again".putstring()'
parser = Parser::Salama.new
out = parser.parse(string_input)
parts = Parser::Transform.new.apply(out)
parts.to_basic
end
end

View File

@ -1,42 +0,0 @@
class StatusView < ElementView
def initialize interpreter
@interpreter = interpreter
end
def draw
@element = div(".status_view") <<
div("h4" , "Interpreter" ) <<
div("button.act" , "Next") <<
div( "br") <<
div("span.clock" , clock_text) <<
div( "br") <<
div("span.state" , state_text) <<
div( "br") <<
div( "span.link" , link_text) <<
div( "br" , "Stdout") <<
div("span.stdout")
# set up event handler
@element.at_css(".act").on("click") { self.update }
return @element
end
def update
@interpreter.tick
@element.at_css(".clock").text = clock_text
@element.at_css(".link").text = link_text
@element.at_css(".stdout").text = @interpreter.stdout
end
def link_text
"Link #{@interpreter.link}"
end
def state_text
"State #{@interpreter.state}"
end
def clock_text
"Instruction #{@interpreter.clock}"
end
end

44
lib/views/classes_view.rb Normal file
View File

@ -0,0 +1,44 @@
require_relative "ref_view"
class ClassesView < ListView
def initialize interpreter
@interpreter = interpreter
@interpreter.register_event(:state_changed, self)
super( class_views )
end
def class_views
classes = []
Parfait.object_space.classes.each do |name , claz|
classes << claz
end
classes.sort! {|a,b| a.name <=> b.name }
classes.collect{|c| ClassView.new(c)}
end
def state_changed old , new_s
return unless new_s == :running
class_views.each_with_index do |v, i|
replace_at i , v
end
end
def draw
super()
wrap_element div("ul.nav!")
wrap_element( div("h4" , "Classes") )
return @element
end
end
class ClassView < RefView
def initialize clazz
super(clazz.name , clazz , 20 )
end
def ref_text
@name
end
end

120
lib/views/html_converter.rb Normal file
View File

@ -0,0 +1,120 @@
class HtmlConverter < AST::Processor
alias :old_process :process
def process s
return "" unless s
#puts s.type
old_process(s)
end
def handler_missing s
puts "Missing: " + s.type
"Missing #{s.type}"
end
def div( statement , html)
"<div class='statement' id='i#{statement.object_id.to_s(16)}'>" + html + "</div>"
end
def span( statement , html)
"<span class='expression' id='i#{statement.object_id.to_s(16)}'>" + html + "</span>"
end
def on_function( statement)
return_type , name , parameters, kids , receiver = *statement
str = return_type + " "
str += receiver + "." if receiver
str += name.to_a.first + "("
str += process(parameters) + ")<br>"
str += process(kids) + "end<br>"
div(statement,str)
end
def on_parameters statement
process_all(statement.children).join(",")
end
def on_parameter p
type , name = *p
span(type,type) + " " + span(name,name)
end
def on_string s
span(s, "'" + s.first + "'")
end
def on_receiver expression
span expression , process(expression.first)
end
def on_field expression
span expression , process(expression.first)
end
def on_field_access statement
receiver_ast , field_ast = *statement
receiver = process(receiver_ast)
field = process(field_ast)
span( statement , receiver + "." + field)
end
def on_field_def statement
type , name , value = *statement
str = span(type, type) + " " + process(name)
str += " = #{process(value)}" if value
div(statement,str)
end
def on_return statement
str = "return " + process(statement.first )
div(statement,str)
end
def on_false_statements s
on_statements s
end
def on_true_statements s
on_statements s
end
def on_statements s
str = ""
s.children.each do |c|
str += process(c).to_s
end
div(s,str)
end
def on_while_statement statement
branch_type , condition , statements = *statement
condition = condition.first
ret = "while_#{branch_type}(" + process(condition) + ")<br>"
ret += process(statements)
ret += "end"
div(statement,ret)
end
def on_if_statement statement
branch_type , condition , if_true , if_false = *statement
condition = condition.first
ret = "if_#{branch_type}(" + process(condition) + ")<br>" + process(if_true)
ret += "else" + "<br>" + process(if_false) if if_false
ret += "end"
div(statement,ret)
end
def on_assignment statement
name , value = *statement
name = process(name)
v = process(value)
str = name + " = " + v
div(statement,str)
end
def on_call c
name , arguments , receiver = *c
ret = process(name)
ret = process(receiver.first) + "." + ret if receiver
ret += "("
ret += process(arguments).join(",")
ret += ")"
span(c,ret)
end
def on_operator_value statement
operator , left_e , right_e = *statement
left_reg = process(left_e)
right_reg = process(right_e)
span(statement , left_reg + " " + operator + " " + right_reg )
end
def on_arguments args
args.children.collect{|c| process(c)}
end
def on_name name
span(name,name.first)
end
def on_int i
span(i , i.first.to_s)
end
end

89
lib/views/left_view.rb Normal file
View File

@ -0,0 +1,89 @@
require_relative "classes_view"
# the whole of the left, ie selection, space and classes
class LeftView < ListView
def initialize( interpreter )
@interpreter = interpreter
super([ SelectView.new(interpreter) ,
ObjectView.new( Parfait.object_space , @interpreter , 26),
ClassesView.new(interpreter) ])
interpreter.register_event(:state_changed, self)
end
# need to re-init when we go to running, as the objects (and the actual space) change
# we replace space and class view with new instances
def state_changed( old , new_s )
return unless new_s == :running
space = ObjectView.new( Parfait.object_space , @interpreter , 26)
replace_at( 1 , space )
replace_at( 2 , ClassesView.new(@interpreter) )
end
def draw
super(".classes")
end
end
# view for the little code select, implemented as a normal expandable menu
#
# on click calls select method
#
# derive from element, meaning we draw
# # TODO: make into listview, so code can be the next level expansion
class SelectView < ElementView
def initialize( interpreter )
super
@interpreter = interpreter
@codes = nil
end
def draw
@element = div("h4.select", "Code") << (list = div("ul.nav!"))
list << (div("li.code_list") << div("a.selected" , "none selected"))
selection_codes unless @codes
@element << div("br")
@element << div("br")
end
def selection_codes
@codes = get_codes.keys
list = div "ul"
@codes.each do |c|
code = div("li") << div("a" , c )
code.style["z-index"] = 10
code.on("click"){ select(c) }
list << code
end
@element.at_css(".code_list") << list
end
# select method set up as click handler for the codes
# restart the interpreter after compiling
def select( code )
puts "selecting #{code}"
@interpreter.set_state :stopped
@element.at_css(".selected").text = code
ruby = as_main(get_codes[code])
compiler = RubyX::RubyXCompiler.new(RubyX.debugger_options)
linker = compiler.ruby_to_binary(ruby, :interpreter)
@interpreter.start_program(linker)
end
def as_main(statements)
"class Space ;def yielder; return yield ; end;def main(arg) ; #{statements}; end; end"
end
def get_codes
{ while_with_calls: 'a = 2; while( 0 < a); a = a - 1;end;return a',
set_internal_byte: "return 'Hello'.set_internal_byte(1,75)" ,
basic_if: 'if( 10 ); return "then";else;return "else";end' ,
plus: 'return 5 + 7' ,
yield: "a = yielder {return 15} ; return a" ,
return: 'return 5' ,
hello_world: "h = 'Hello World'.putstring;return h",
dynamic_call: "a = 150 ; return a.div10",
}
end
end

43
lib/views/mom_view.rb Normal file
View File

@ -0,0 +1,43 @@
require "base/constant_view"
require "base/list_view"
class MomView < ListView
def initialize interpreter
@interpreter = interpreter
@current = nil
super([start_view])
@interpreter.register_event(:instruction_changed, self)
@interpreter.register_event(:state_changed, self)
end
def start_view
ConstantView.new( "span.mom_bright" , "starting" )
end
def instruction_changed
i = @interpreter.instruction
return unless i && i.source.is_a?(Mom::Instruction)
return if i.source == @current
@current = i.source
@element.at_css(".mom_bright").remove_class("mom_bright")
instruction = append_view( ConstantView.new( "span.mom_bright" , @current.to_s ) )
wrap_node_with( instruction , div )
remove_first if( @elements.length > 6)
end
def draw
super()
wrap_node_with @elements.first , div
wrap_element div(".mom_view") << div("h4" ,"Mom::Instruction")
@element
end
def state_changed(old , new_s)
return unless new_s == :running
clear_view
@current = nil
append_view start_view
end
end

73
lib/views/object_view.rb Normal file
View File

@ -0,0 +1,73 @@
require_relative "ref_view"
class ObjectView < ListView
# z is the z-index
def initialize object , interpreter = nil , z = nil
@object = object
@z = z
@interpreter = interpreter
@interpreter.register_event(:object_changed, self) if interpreter
super( content_elements )
end
def draw
@element = super(@interpreter ? "ul.nav!" : "ul")
prepend_element div( "li" ) << div("span" , class_header )
return @element
end
def object_changed( reg , at)
#puts "Object changed in #{reg} , at #{at}"
for_object = @interpreter.get_register( reg )
return unless for_object == @object
#puts "Object changed #{for_object} , at #{at}"
variable = @object.get_instance_variables.get(at)
if(variable)
f = @object.get_instance_variable(variable)
else
variable = at.to_s
f = @object.get_internal_word(at)
end
#puts "got var name #{variable}#{variable.class} for #{at}, #{f}"
view = RefView.new( variable , f , @z )
if( @children[at + 1] )
replace_at(at + 1, view)
else
append_view(view)
end
end
def class_header
str = Risc::Position.set?(@object).to_s
clazz = @object.class.name.split("::").last
[clazz, str].join " : "
end
def content_elements
fields = [ConstantView.new("li" , "------------------------------")]
object = @object
if object and ! object.is_a?(String)
object.get_instance_variables.each do |variable|
f = object.get_instance_variable(variable)
fields << RefView.new( variable , f , @z )
end
if( object.is_a?(Parfait::List) )
index = 0
object.each do | o|
fields << RefView.new( index.to_s , o , @z )
index += 1
end
end
if( object.is_a?(Parfait::Integer) )
fields << RefView.new( 3.to_s , object.value , @z )
end
if( object.is_a?(Parfait::Word) )
fields << RefView.new( 3.to_s , object.to_string , @z )
end
end
fields
end
end

View File

@ -15,44 +15,54 @@ class RefView < ListView
end
def draw
@element = div("li") << div("a" , "#{@name} : #{marker(@value)}" )
@element = div("li") << div("a" , ref_text )
add_hover
@element.style["z-index"] = @z if @z
@element
end
def ref_text
"#{@name} : #{marker()}"
end
def add_hover
return if is_string?
@element.on("hover"){ hover } if is_object?(@value)
end
def is_object?( )
Virtual.machine.objects[@value] != nil
return false if @value.is_a?(Fixnum)
return false unless @value
! is_label?
end
def is_string?()
Virtual.machine.objects[@value].is_a? String
@value.is_a? String
end
def is_label?
@value.is_a?(Risc::Label)
end
def is_nil?()
Virtual.machine.objects[@value].nil?
@value.nil?
end
def hover
puts "hovering #{@name}"
#puts "hovering #{@name}"
append_view ObjectView.new(@value)
@element.off("hover")
end
def marker id
def marker
if is_string?
str = @value
elsif is_nil?
str = "nil"
elsif is_object?
str = Risc::Position.get(@value).to_s
elsif is_label?
str = "Label"
else
var = Virtual.machine.objects[id]
str = var.class.name.split("::").last[0,2]
str + " : #{id.to_s}"
str = @value.to_s
end
end

View File

@ -21,11 +21,16 @@ class RegistersView < ListView
@element
end
def register_changed reg , old , value
def register_changed( reg , old , value )
reg = reg.symbol unless reg.is_a? Symbol
index = reg.to_s[1 .. -1 ].to_i
if( is_object? value )
swap = ObjectView.new( value , @interpreter , 16 - index )
has = Risc::Position.set?(value)
if( has )
if has.object.is_a?(Risc::Label)
swap = ValueView.new "Label: #{has.object.name}"
else
swap = ObjectView.new( value , @interpreter , 16 - index )
end
else
swap = ValueView.new value
end
@ -33,10 +38,6 @@ class RegistersView < ListView
# @elements[index].style["z-index"] = -index
end
def is_object?( id )
Virtual.machine.objects[id] != nil
end
end
class ValueView < ElementView
@ -46,6 +47,8 @@ class ValueView < ElementView
end
def draw
@element = div("ul.nav!") << div("li") << div("span", @value)
li = div("li")
li << div("span", @value)
@element = div("ul.nav!") << li
end
end

42
lib/views/risc_view.rb Normal file
View File

@ -0,0 +1,42 @@
require "base/constant_view"
require "base/list_view"
class RiscView < ListView
def initialize interpreter
@interpreter = interpreter
super([start_view])
@interpreter.register_event(:instruction_changed, self)
@interpreter.register_event(:state_changed, self)
end
def start_view
ConstantView.new( "span.risc_bright" , "starting" )
end
def instruction_changed
@element.at_css(".risc_bright").remove_class("risc_bright")
instruction = append_view( ConstantView.new( "span.risc_bright" , instruction_text ) )
wrap_node_with instruction , div
remove_first if( @elements.length > 6)
end
def draw
super()
wrap_node_with @elements.first , div
wrap_element div(".risc_view") << div("h4" ,"Register Machine Instruction")
@element
end
def state_changed old , new_s
return unless new_s == :running
clear_view
append_view start_view
end
def instruction_text
return "" unless @interpreter.instruction
@interpreter.instruction.to_s
end
end

85
lib/views/status_view.rb Normal file
View File

@ -0,0 +1,85 @@
require "browser/delay"
class StatusView < ElementView
def initialize interpreter
@interpreter = interpreter
@running = false
end
def draw
header = div("h4" , "Interpreter" )
header << div("span.header_state" , state_text)
@element = div(".status_view") <<
header <<
div("button.next" , "Next") <<
div("button.run" , "Run") <<
div("button.wizz" , "Wizz") <<
div( "br") <<
div("span.clock" , clock_text) <<
div( "br") <<
div("span.flags" , flags_text) <<
div( "br") <<
div( "span.stdout" , "Stdout") <<
div( "br") <<
div( "span.status" , "Status")
# set up event handler
@element.at_css(".next").on("click") { self.update }
@element.at_css(".run").on("mousedown") { self.start( 0.1 ) }
@element.at_css(".wizz").on("mousedown") { self.start( 0.0 ) }
@element.at_css(".run").on("mouseup") { self.stop }
@element.at_css(".wizz").on("mouseup") { self.stop }
return @element
end
def start(speed)
@running = speed
run
end
def stop
@running = false
end
def run
return unless @running
proc = Proc.new do
self.update
self.run
end
proc.after( @running )
end
def update
@interpreter.tick
@element.at_css(".clock").text = clock_text
@element.at_css(".header_state").text = state_text
@element.at_css(".flags").text = flags_text
@element.at_css(".stdout").text = @interpreter.stdout
@element.at_css(".status").text = status_text
end
def status_text
return unless @interpreter.instruction
return "#{@interpreter.instruction.to_s}" unless @interpreter.instruction.source
source = @interpreter.instruction.source
s = "#{source.to_s}"
if( source.respond_to?(:source) and source.source )
s += @interpreter.instruction.source.source.to_s
end
s
end
def state_text
" (#{@interpreter.state})"
end
def flags_text
flags = []
@interpreter.flags.each do |name,value|
flags << name if value
end
"Flags #{flags.join(':')}"
end
def clock_text
"Instruction #{@interpreter.clock}-0x#{@interpreter.pc.to_s(16)}"
end
end

46
lib/views/vool_view.rb Normal file
View File

@ -0,0 +1,46 @@
require_relative "html_converter"
class VoolView < ElementView
def initialize interpreter
@interpreter = interpreter
@interpreter.register_event(:instruction_changed, self)
end
def draw
@text = div(".text")
@ticker = div(".ticker")
@element = div(".vool_view") << div("h4.source" , "Class.Method") << @ticker << @text
@element
end
def instruction_changed
i = @interpreter.instruction
return "" unless i
if i.is_a?(Risc::FunctionReturn)
link = @interpreter.get_register( i.register )
puts "Link #{link}:#{link.class}"
raise "No link method" unless link
end
method = nil
case i.source
when Mom::Instruction
if(i.source.is_a?(Mom::SimpleCall))
method = i.source.method
end
#TODO, give mom a source
when Parfait::Callable
method = i.source
when String
return
else
raise "Unrecognized source #{i.source.class.name} for #{i}"
end
update_method(method) if method
end
def update_method(method)
@text.inner_html = method.name
end
end

View File

@ -1,5 +0,0 @@
require 'spec_helper'
describe 'sample http controller test', type: :http_controller do
# Specs here
end

View File

@ -1,11 +0,0 @@
require 'spec_helper'
describe 'sample integration test', type: :feature do
# An example integration spec, this will only be run if ENV['BROWSER'] is
# specified. Current values for ENV['BROWSER'] are 'firefox' and 'phantom'
it 'should load the page' do
visit '/'
expect(page).to have_content('Home')
end
end

View File

@ -1,5 +0,0 @@
require 'spec_helper'
describe 'sample model' do
# Specs here
end

View File

@ -1,5 +0,0 @@
require 'spec_helper'
describe 'sample task', type: :task do
# Specs here
end

View File

@ -1,14 +0,0 @@
# Volt sets up rspec and capybara for testing.
require 'volt/spec/setup'
Volt.spec_setup
RSpec.configure do |config|
config.run_all_when_everything_filtered = true
config.filter_run :focus
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = 'random'
end

BIN
static/debugger.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB