Compare commits

...

157 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
c0bdfe149c fix list and string views 2015-08-25 11:54:44 +02:00
Torsten Ruger
5ec7ea6d56 small fix 2015-08-25 09:57:22 +02:00
Torsten Ruger
ee788b3507 add layout to object view 2015-08-25 09:57:08 +02:00
Torsten Ruger
85e099382d fix method update 2015-08-24 02:19:41 +02:00
Torsten Ruger
7d214e7013 finish off instruction view (+small rename) 2015-08-24 02:04:07 +02:00
Torsten Ruger
c5a07be6ac inlined mini clases 2015-08-24 01:49:41 +02:00
Torsten Ruger
b3de7c9b5e implement instruction view , almost complete 2015-08-24 01:45:33 +02:00
Torsten Ruger
516b041bed small improvements 2015-08-24 01:44:50 +02:00
Torsten Ruger
a25d292e1f improve style a bit 2015-08-24 01:44:04 +02:00
Torsten Ruger
167353fdf3 update method name 2015-08-23 02:28:31 +02:00
Torsten Ruger
95c4d656b3 last DOM cleaning 2015-08-23 02:20:36 +02:00
Torsten Ruger
3319b0cd98 fix the z index 2015-08-23 02:16:32 +02:00
Torsten Ruger
7820c5eff0 clean of DOM 2015-08-23 02:16:13 +02:00
Torsten Ruger
a56e811699 small fix and expansion to 5 level 2015-08-23 02:15:34 +02:00
Torsten Ruger
83e0c8a925 now very simple to get expanding objects 2015-08-22 21:17:32 +02:00
Torsten Ruger
7885ae93c4 redo object view as list, introduce ref view 2015-08-22 20:11:33 +02:00
Torsten Ruger
caa1da342c remove the root function (pass to super now) 2015-08-22 19:28:09 +02:00
Torsten Ruger
b8a0e5f8a3 fix blocks to change 2015-08-22 18:37:42 +02:00
Torsten Ruger
b43bffc940 remove DOM usage from blocks, make it list view 2015-08-22 17:30:27 +02:00
Torsten Ruger
1ad5681827 remove DOM usage from object 2015-08-22 17:19:07 +02:00
Torsten Ruger
cf1d32e520 objects back on screen, not updating yet 2015-08-22 02:40:19 +02:00
Torsten Ruger
68f67eda54 registers ticking, but objects not showing 2015-08-22 02:23:53 +02:00
Torsten Ruger
ed2a054ca6 starting interpreter and getting ticks going (slowly) 2015-08-22 01:59:29 +02:00
Torsten Ruger
3fa685a0bb assign @element explicitly (remove create_element) 2015-08-22 01:37:15 +02:00
Torsten Ruger
0d4813df13 added separate class view and made classes view a listview 2015-08-22 01:36:11 +02:00
Torsten Ruger
5f2f35cbcf debug by environment (stop endless editing) 2015-08-22 01:35:21 +02:00
Torsten Ruger
15fd4ea7c6 remove some DOM usage 2015-08-22 01:06:48 +02:00
Torsten Ruger
b21ca406c8 rename create_element to div and create to create_element 2015-08-22 01:05:35 +02:00
Torsten Ruger
6925a3fefa bit of organizing 2015-08-21 20:05:49 +02:00
Torsten Ruger
c49c73bb3d starting on register view, next up events 2015-08-21 19:07:27 +02:00
Torsten Ruger
8b743fbcd5 moving functionality in the base classes for all to share 2015-08-21 19:07:02 +02:00
Torsten Ruger
977156ba51 start on block view 2015-08-21 00:37:41 +02:00
Torsten Ruger
287277ef59 basic status view (without updates) 2015-08-20 20:03:00 +02:00
Torsten Ruger
0e430e8b00 cleanup of class view 2015-08-20 20:02:40 +02:00
Torsten Ruger
a6c22cf6e0 change to underscore in class names, for paggio 2015-08-20 20:02:25 +02:00
Torsten Ruger
5c60f29fbf and the class instances. nice to use objects 2015-08-20 19:46:43 +02:00
Torsten Ruger
87c649c622 put the classes back on the screen 2015-08-20 19:40:47 +02:00
Torsten Ruger
1f7c06d626 add some explanation and use github gem versions 2015-08-20 16:13:57 +02:00
Torsten Ruger
ef1235d3e8 small preparations 2015-08-20 16:07:44 +02:00
Torsten Ruger
ef60cbdc45 introduce base classes 2015-08-20 14:48:45 +02:00
Torsten Ruger
e7e85b8d73 revived the styles 2015-08-20 02:14:33 +02:00
Torsten Ruger
bb5caa9bf1 speed up by 50 using men cache 2015-08-20 00:53:39 +02:00
Torsten Ruger
3c959fecb2 initial steps 2015-08-20 00:53:20 +02:00
Torsten Ruger
4257bc446f fix, was outdated 2015-08-19 22:34:39 +02:00
Torsten Ruger
a49ef347ff more opal changes 2015-07-14 16:03:06 +03:00
Torsten Ruger
71ed4f60d7 more transition 2015-07-14 14:21:33 +03:00
Torsten Ruger
7d2120fdd5 removing more volt 2015-07-14 14:10:11 +03:00
Torsten Ruger
9af1937a71 first step of switch to opal 2015-07-14 14:08:28 +03:00
68 changed files with 1426 additions and 976 deletions

42
Gemfile
View File

@ -1,41 +1,21 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'volt', '0.9.5.pre4' gem "opal"
gem 'opal-sprockets'
gem 'opal-browser'
# volt uses mongo as the default data store. gem "rubyx" , "0.6" , path: "../rubyx"
gem 'volt-mongo', '~> 0.1.0'
gem "parslet" , git: "https://github.com/salama/parslet.git" gem "rx-file" , :git => "https://github.com/ruby-x/rx-file"
#gem "salama" , git: "https://github.com/salama/salama.git"
gem "salama" , path: "../salama"
gem "salama-reader" , git: "https://github.com/salama/salama-reader.git"
gem "salama-arm" , git: "https://github.com/salama/salama-arm.git"
gem "salama-object-file" , git: "https://github.com/salama/salama-object-file.git"
gem "susy" , "2.2.5"
# Asset compilation gems, they will be required when needed. gem "sass"
gem 'csso-rails', '~> 0.3.4', require: false
gem 'uglifier', '>= 2.4.0', require: false
#gem "foundation" , :github => "zurb/foundation"
group :test do group :test do
# Testing dependencies # Testing dependencies
gem "minitest" gem "minitest"
gem 'rspec', '~> 3.2.0' gem 'rspec'
gem 'opal-rspec', '~> 0.4.2' gem 'capybara'
gem 'capybara', '~> 2.4.2' gem 'selenium-webdriver'
gem 'selenium-webdriver', '~> 2.43.0' gem 'chromedriver2-helper'
gem 'chromedriver2-helper', '~> 0.0.8' gem 'poltergeist'
gem 'poltergeist', '~> 1.5.0'
end
# Server for MRI
platform :mri, :mingw do
# The implementation of ReadWriteLock in Volt uses concurrent ruby and ext helps performance.
gem 'concurrent-ruby-ext', '~> 0.8.0'
# Thin is the default volt server, Puma is also supported
gem 'thin', '~> 1.6.0'
gem 'bson_ext', '~> 1.9.0'
end end

View File

@ -1,186 +1,120 @@
GIT GIT
remote: https://github.com/salama/parslet.git remote: https://github.com/ruby-x/rx-file
revision: beeb9b441a9ade1504f7f0e848d805e36a02c544 revision: 7c4a5546136d1bad065803da91778b209c18cb4d
specs: specs:
parslet (1.7.0) rx-file (0.3.0)
GIT
remote: https://github.com/salama/salama-arm.git
revision: 0bd5091e3f284ecf040e0086a41d2449cd5afb7a
specs:
salama-arm (0.0.1)
GIT
remote: https://github.com/salama/salama-object-file.git
revision: fbae6a02764dbe97e01e4833f9ffffe09879b100
specs:
salama-object-file (0.2.0)
GIT
remote: https://github.com/salama/salama-reader.git
revision: 841592c667acea1e796f950851262e6938b231bc
specs:
salama-reader (0.2.0)
parslet (~> 1.7.0)
PATH PATH
remote: ../salama remote: ../rubyx
specs: specs:
salama (0.2.0) rubyx (0.6.0)
salama-object-file (~> 0.2) parser (~> 2.3.0)
salama-reader (~> 0.2) rx-file (~> 0.3)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
bcrypt (3.1.10) addressable (2.6.0)
bson (1.9.2) public_suffix (>= 2.0.2, < 4.0)
bson_ext (1.9.2) ast (2.4.0)
bson (~> 1.9.2) capybara (3.13.2)
capybara (2.4.4) addressable
mime-types (>= 1.16) mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3) nokogiri (~> 1.8)
rack (>= 1.0.0) rack (>= 1.6.0)
rack-test (>= 0.5.4) rack-test (>= 0.6.3)
xpath (~> 2.0) regexp_parser (~> 1.2)
childprocess (0.5.6) xpath (~> 3.2)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11) ffi (~> 1.0, >= 1.0.11)
chromedriver2-helper (0.0.8) chromedriver2-helper (0.0.10)
nokogiri nokogiri
cliver (0.3.2) cliver (0.3.2)
coderay (1.1.0) concurrent-ruby (1.1.4)
concurrent-ruby (0.8.0) diff-lcs (1.3)
ref (~> 1.0, >= 1.0.5) ffi (1.10.0)
concurrent-ruby-ext (0.8.0)
concurrent-ruby (~> 0.8.0)
configurations (2.0.0)
csso-rails (0.3.4)
execjs (>= 1)
daemons (1.2.3)
diff-lcs (1.2.5)
eventmachine (1.0.8)
execjs (2.5.2)
faye-websocket (0.10.0)
eventmachine (>= 0.12.0)
websocket-driver (>= 0.5.1)
ffi (1.9.10)
hike (1.2.3) hike (1.2.3)
json (1.8.3) mini_mime (1.0.1)
listen (3.0.3) mini_portile2 (2.4.0)
rb-fsevent (>= 0.9.3) minitest (5.11.3)
rb-inotify (>= 0.9) nokogiri (1.10.1)
method_source (0.8.2) mini_portile2 (~> 2.4.0)
mime-types (2.6.1) opal (0.11.4)
mini_portile (0.6.2) ast (>= 2.3.0)
minitest (5.8.0)
mongo (1.9.2)
bson (~> 1.9.2)
multi_json (1.11.2)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
opal (0.8.0)
hike (~> 1.2) hike (~> 1.2)
parser (= 2.3.3.1)
sourcemap (~> 0.1.0) sourcemap (~> 0.1.0)
opal-browser (0.2.0)
opal
paggio
opal-sprockets (0.4.2.0.11.0.3.1)
opal (~> 0.11.0)
sprockets (~> 3.1) sprockets (~> 3.1)
tilt (>= 1.4) tilt (>= 1.4)
opal-rspec (0.4.3) paggio (0.2.6)
opal (>= 0.7.0, < 0.9) parser (2.3.3.1)
poltergeist (1.5.1) ast (~> 2.2)
capybara (~> 2.1) poltergeist (1.18.1)
capybara (>= 2.1, < 4)
cliver (~> 0.3.1) cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0) websocket-driver (>= 0.2.0)
pry (0.10.1) public_suffix (3.0.3)
coderay (~> 1.1.0) rack (2.0.6)
method_source (~> 0.8.1) rack-test (1.1.0)
slop (~> 3.4) rack (>= 1.0, < 3)
rack (1.5.5) rb-fsevent (0.10.3)
rack-test (0.6.3) rb-inotify (0.10.0)
rack (>= 1.0) ffi (~> 1.0)
rb-fsevent (0.9.5) regexp_parser (1.3.0)
rb-inotify (0.9.5) rspec (3.8.0)
ffi (>= 0.5.0) rspec-core (~> 3.8.0)
ref (1.0.5) rspec-expectations (~> 3.8.0)
rspec (3.2.0) rspec-mocks (~> 3.8.0)
rspec-core (~> 3.2.0) rspec-core (3.8.0)
rspec-expectations (~> 3.2.0) rspec-support (~> 3.8.0)
rspec-mocks (~> 3.2.0) rspec-expectations (3.8.2)
rspec-core (3.2.3)
rspec-support (~> 3.2.0)
rspec-expectations (3.2.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0) rspec-support (~> 3.8.0)
rspec-mocks (3.2.1) rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0) rspec-support (~> 3.8.0)
rspec-support (3.2.2) rspec-support (3.8.0)
rubyzip (1.1.7) rubyzip (1.2.2)
sass (3.4.16) sass (3.7.3)
selenium-webdriver (2.43.0) 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) childprocess (~> 0.5)
multi_json (~> 1.0) rubyzip (~> 1.2, >= 1.2.2)
rubyzip (~> 1.0)
websocket (~> 1.0)
slop (3.6.0)
sourcemap (0.1.1) sourcemap (0.1.1)
sprockets (3.2.0) sprockets (3.7.2)
rack (~> 1.0) concurrent-ruby (~> 1.0)
susy (2.2.5) rack (> 1, < 3)
sass (>= 3.3.0, < 3.5) tilt (2.0.9)
thin (1.6.3) websocket-driver (0.7.0)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0)
rack (~> 1.0)
thor (0.19.1)
tilt (2.0.1)
uglifier (2.7.1)
execjs (>= 0.3.0)
json (>= 1.8.0)
volt (0.9.5.pre4)
bcrypt (~> 3.1.9)
bundler (>= 1.5)
concurrent-ruby (= 0.8.0)
configurations (~> 2.0.0.pre)
faye-websocket (~> 0.10.0)
listen (~> 3.0.1)
opal (~> 0.8.0)
pry (~> 0.10.1)
rack (~> 1.5.0)
sass (~> 3.4.15)
thor (~> 0.19.0)
volt-mongo (0.1.1)
mongo (~> 1.9.0)
websocket (1.2.2)
websocket-driver (0.6.2)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2) websocket-extensions (0.1.3)
xpath (2.0.0) xpath (3.2.0)
nokogiri (~> 1.3) nokogiri (~> 1.8)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
bson_ext (~> 1.9.0) capybara
capybara (~> 2.4.2) chromedriver2-helper
chromedriver2-helper (~> 0.0.8)
concurrent-ruby-ext (~> 0.8.0)
csso-rails (~> 0.3.4)
minitest minitest
opal-rspec (~> 0.4.2) opal
parslet! opal-browser
poltergeist (~> 1.5.0) opal-sprockets
rspec (~> 3.2.0) poltergeist
salama! rspec
salama-arm! rubyx (= 0.6)!
salama-object-file! rx-file!
salama-reader! sass
selenium-webdriver (~> 2.43.0) selenium-webdriver
susy (= 2.2.5)
thin (~> 1.6.0)
uglifier (>= 2.4.0)
volt (= 0.9.5.pre4)
volt-mongo (~> 0.1.0)
BUNDLED WITH BUNDLED WITH
1.10.5 1.17.2

127
README.md
View File

@ -1,36 +1,117 @@
# Debugger # Debugger
After some tryouts it ended up being an Opal application. That is ruby as javascript in the browser. After some tryouts it ended up being an Opal application. That is ruby as javascript in the browser.
Below is a screenshot.
![Debugger](https://raw.githubusercontent.com/salama/salama-debugger/master/static/debugger.png) ![Debugger](https://raw.githubusercontent.com/rubyx/rubyx-debugger/master/static/debugger.png)
- On the left are the classes of the system. Next idea is to have hover info about them. ## Views
- Next a source code view (not implemented)
- next a view of the Virtual Instructions
- last section, current block with current Register Instruction highlighted
- step (next) button for single stepping
- status: starting , running , exited
- bottom row are the registers. If the register hold an object the variables are shown.
(also should have hover info) , the first letter indicates the class, the number is the address
So lots to do, but a good start. 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)
### Source View
I don't want to use gdb anymore, and it would be easier without using the qemu setup, so: 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.
- single step debugging of the register machine level (as close to arm as need be) While stepping through the code, those parts of the code that are active get highlighted in blue.
- visual transitions for steps
- visualisation of data in registers (some kind of link to the object) Currently stepping is done only in register instructions, which means that depending on the source
- show the current instruction and a few around constructs it may take many steps for the cursor to move on.
- show vm object (message etc)
- show effect of register transitions on vm objects Each step will show progress on the register level though (next view)
- visualize vm object content (again some links)
# Space ### Register Instruction view
- Visualise the object space in some way Salama defines a register machine level which is quite close to the arm machine, but with more
- Visualise single object, bit like atoms sensible names. It has 16 registers (below) and an instruction set that is useful for Soml.
- values immediate
- objects as link 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

View File

@ -1,59 +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: 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);
}
.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;
}
.bright {
background-color: orange ;
}

View File

@ -1,59 +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.05em;
margin-top : -1.35em;
}
#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 : #F6C739;
}
#nav li:hover ul ul, #nav li:hover ul ul ul {
left: -999em;
}
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul { /* lists nested under hovered list items */
left: auto;
}

View File

@ -1,2 +0,0 @@
# Specify which components you wish to include when
# the "home" component loads.

View File

@ -1,10 +0,0 @@
# Place any code you want to run when the component is included on the client
# or server.
# To include code only on the client use:
# if RUBY_PLATFORM == 'opal'
#
# To include code only on the server, use:
# unless RUBY_PLATFORM == 'opal'
# ^^ this will not send compile in code in the conditional to the client.
# ^^ this include code required in the conditional.

View File

@ -1,8 +0,0 @@
# See https://github.com/voltrb/volt#routes for more info on routes
client '/about', action: 'about'
# The main route, this should be last. It will match any params not
# previously matched.
client '/', {}

View File

@ -1,12 +0,0 @@
module Main
class BlocksController < Volt::ModelController
def initialize *args
super(*args)
blocks = BlocksModel.new
page._blocks = blocks
@volt_app.interpreter.register_event(:instruction_changed, blocks)
end
end
end

View File

@ -1,28 +0,0 @@
module Main
class ClassesController < Volt::ModelController
def initialize *args
super(*args)
page._classes!.clear
all = []
Virtual.machine.space.classes.each do |name , claz|
next if [:Kernel,:Module,:MetaClass,:BinaryCode].index name
all << name
end
all.sort.each do |name|
c = Volt::Model.new :name => name
page._classes << c
end
end
def variables(clas_model)
layout = Virtual.machine.space.get_class_by_name(clas_model._name).object_layout
vars = []
layout.object_instance_names.each do |name|
vars.push name
end
vars
end
end
end

View File

@ -1,43 +0,0 @@
# By default Volt generates this controller for your Main component
require "salama"
require "interpreter/interpreter"
module Main
class MainController < Volt::ModelController
def initialize *args
super(*args)
@volt_app.class.attr_accessor :interpreter
@volt_app.interpreter = Interpreter::Interpreter.new
end
def index
init_machine
end
private
def init_machine
machine = Virtual.machine.boot
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"
page._interpreter = { }
@volt_app.interpreter.start machine.init
end
# The main template contains a #template binding that shows another
# template. This is the path to that template. It may change based
# on the params._component, params._controller, and params._action values.
def main_path
"#{params._component || 'main'}/#{params._controller || 'main'}/#{params._action || 'index'}"
end
# Determine if the current nav component is the active one by looking
# at the first part of the url against the href attribute.
def active_tab?
url.path.split('/')[1] == attrs.href.split('/')[1]
end
end
end

View File

@ -1,55 +0,0 @@
if RUBY_PLATFORM == 'opal'
require "native"
end
module Main
class ObjectsController < Volt::ModelController
def index_ready
container = Native(self.container).querySelector("ul")
all = container.querySelectorAll("a")
len = all.length - 1
while len >= 0
puts "li #{len}" + all.item(len).innerHTML + " lo"
len = len - 1
end
# red = -> (event) { container.style.backgroundColor = "red" }
red = -> (event) { puts container.innerHTML }
container.addEventListener("mouseenter" , red)
end
def marker id
var = Virtual.machine.objects[id]
if var.is_a? String
str "Wo"
else
str = var.class.name.split("::").last[0,2]
end
str + " : #{id.to_s}"
end
def class_header(id)
object = Virtual.machine.objects[id]
return "" unless object
clazz = object.class.name.split("::").last
"#{clazz}:#{id}"
end
def content(id)
object = Virtual.machine.objects[id]
fields = []
if object and ! object.is_a?(String)
object.get_instance_variables.each do |variable|
f = object.get_instance_variable(variable)
fields << ["#{variable} : #{marker(f.object_id)}" , f.object_id]
end
end
fields
end
def is_object?( id )
Virtual.machine.objects[id] != nil
end
end
end

View File

@ -1,26 +0,0 @@
module Main
class RegistersController < Volt::ModelController
def initialize *args
super(*args)
self.model = []
init_registers
end
def init_registers
@volt_app.interpreter.registers.each do |reg , val|
r = RegisterModel.new( :name => reg , :value => val)
self.model << r
@volt_app.interpreter.register_event(:register_changed, r)
@volt_app.interpreter.register_event(:object_changed, r)
r.register_changed( reg , nil , @volt_app.interpreter.registers[reg])
end
end
def is_object?( id )
Virtual.machine.objects[id] != nil
end
end
end

View File

@ -1,12 +0,0 @@
module Main
class SourcesController < Volt::ModelController
def initialize *args
super(*args)
sources = SourceModel.new
page._sources = sources
@volt_app.interpreter.register_event(:instruction_changed, sources)
end
end
end

View File

@ -1,31 +0,0 @@
module Main
class StatusController < Volt::ModelController
def initialize *args
super(*args)
self.model = Volt::Model.new
update_interpreter
end
def tick
@volt_app.interpreter.tick
update_interpreter
end
def update_interpreter
self._clock = @volt_app.interpreter.clock
self._state = @volt_app.interpreter.state
self._stdout = @volt_app.interpreter.stdout
self._link = @volt_app.interpreter.link.to_s
page._method_name = method_name
page._block_name = @volt_app.interpreter.block ? @volt_app.interpreter.block.name : " "
end
def method_name
bl = @volt_app.interpreter.block
return " " unless bl
return bl.method if bl.method.is_a? String
"#{bl.method.for_class.name}.#{bl.method.name}"
end
end
end

View File

@ -1,10 +0,0 @@
class BlocksModel < Volt::ArrayModel
def instruction_changed old , ins
self.last._class_name = "inactive" if( self.length > 0)
self << { :name => ins.to_s , :class_name => "bright" }
#puts "block #{self.length}"
self.delete_at(0) if( self.length > 5)
end
end

View File

@ -1,36 +0,0 @@
class RegisterModel < Volt::Model
field :name
field :value
field :fields
def register_changed reg , old , value
reg = reg.symbol unless reg.is_a? Symbol
return unless reg == name
self.value = value
calc_fields
end
def object_changed reg
reg = reg.symbol unless reg.is_a? Symbol
return unless reg == name
#puts "Object changed in #{reg}"
calc_fields
end
def calc_fields
#puts "My id #{objects_id} , #{objects_id.class}"
object = Virtual.machine.objects[value]
self.fields.clear
if object and ! object.is_a?(String)
clazz = object.class.name.split("::").last
#puts "found #{clazz}"
self.fields << "#{clazz}:#{object.internal_object_length}"
self.fields << object.get_layout
object.get_instance_variables.each do |variable|
f = object.get_instance_variable(variable)
self.fields << f
end
end
end
end

View File

@ -1,23 +0,0 @@
class SourceModel < Volt::ArrayModel
def instruction_changed old , ins
return unless ins
source = source_text ins.source
if( self.length > 0)
return if self.last._name == source
self.last._class_name = "inactive"
end
self << { :name => source.to_s , :class_name => "bright" }
#puts "sources #{self.length}"
self.delete_at(0) if( self.length > 5)
end
def source_text source
if source.is_a? Virtual::Instruction
return source.class.name
else
return "Method: #{source.name}"
end
end
end

View File

@ -1,11 +0,0 @@
require "salama-reader"
class ParseTask < Volt::Task
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,17 +0,0 @@
<:Title>
blocks index
<:Body>
<div class="block-view">
<div>
<h4> {{page._method_name}} </h4>
<h4> Block: {{page._block_name}} </h4>
</div>
{{ page._blocks.each do |b| }}
<div>
<span class="{{b._class_name}}">
{{b._name}}
</span>
</div>
{{ end }}
</div>

View File

@ -1,23 +0,0 @@
<:Title>
classes index
<:Body>
<div class="classes">
<h4> Classes </h4>
<ul id="nav">
{{page._classes.each do |clas| }}
<li>
<a href="#">{{ clas._name }}</a>
{{ unless variables(clas).empty? }}
<ul>
{{variables(clas).each do |var| }}
<li>
<a href="#">{{var}}</a>
</li>
{{ end }}
</ul>
{{ end }}
</li>
{{end}}
</ul>
</div>

View File

@ -1,16 +0,0 @@
<:Title>
Home
<:Body>
<:classes />
<div class="file-view">
</div>
<:sources />
<:blocks />
<:status/>
<:registers/>

View File

@ -1,12 +0,0 @@
<:Title>
{{ view main_path, "title", {controller_group: 'main'} }}
<:Body>
<div class="debugger_view">
<:volt:notices />
{{ view main_path, 'body', {controller_group: 'main'} }}
</div>

View File

@ -1,15 +0,0 @@
<:Title>
objects index
<:Body>
<ul sid={{attrs.id}}>
<li>
<span>{{class_header(attrs.id)}}</span>
</li>
<li>&nbsp;&nbsp;-------------------------</li>
{{content(attrs.id).each do |con3| }}
<li>
<a href="#">{{con3[0]}}</a>
</li>
{{end}}
</ul>

View File

@ -1,19 +0,0 @@
<:Title>
registers index
<:Body>
<div class="registers-view">
{{ model.each do |reg| }}
<div class="register-view" id="nav">
{{ if(is_object?(reg.value) ) }}
<:objects id={{reg.value}} />
{{else}}
<ul>
<li>
<a href="#">{{reg.value}}</a>
</li>
</ul>
{{ end }}
</div>
{{end}}
</div>

View File

@ -1,14 +0,0 @@
<:Title>
sources index
<:Body>
<div class="source-view">
<h4> Virtual Machine Instruction </h4>
{{page._sources.each do |source| }}
<div>
<span class="{{source._class_name}}">
{{source._name}}
</span>
</div>
{{end}}
</div>

View File

@ -1,17 +0,0 @@
<:Title>
status index
<:Body>
<div class="status-view">
<h4> Interpreter </h4>
Instruction {{ _clock}}
<button e-click="tick"> Next </button>
<br/>
<span> State </span>
<span> {{_state}} </span>
<br/>
<span> Link: {{_link}} </span>
<br/>
Stdout <br/>
<span> {{_stdout}} </span>
</div>

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

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

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,4 +1,16 @@
# Run via rack server require 'bundler'
require 'bundler/setup' Bundler.require
require 'volt/server' require 'tilt/erb'
run Volt::Server.new.app require "opal"
require 'opal-sprockets'
Opal.use_gem("rubyx")
run Opal::Sprockets::Server.new { |s|
s.main = 'debugger.js.rb'
s.append_path 'lib'
s.append_path 'assets'
s.debug = !ENV["DEBUG"].nil?
s.index_path = "index.html.erb"
s.sprockets.cache = Sprockets::Cache::MemoryStore.new(50000)
}

View File

@ -1,136 +0,0 @@
# app.rb is used to configure your app. This code is only run on the server,
# then any config options in config.public are passed to the client as well.
#hint_path = Bundler.definition.specs["simptip"].first.full_gem_path
#ENV["SASS_PATH"] = ENV["SASS_PATH"] + File::PATH_SEPARATOR + hint_path
Volt.configure do |config|
# Setup your global app config here.
#######################################
# Basic App Info (stuff you should set)
#######################################
config.domain = 'salama-debugger.com'
config.app_name = 'Salama-debugger'
config.mailer.from = 'Salama-debugger <no-reply@salama-debugger.com>'
############
# App Secret
############
# Your app secret is used for signing things like the user cookie so it can't
# be tampered with. A random value is generated on new projects that will work
# without the need to customize. Make sure this value doesn't leave your server.
#
# For added security we recommend moving the app secret into an environment. You can
# setup that like so:
#
# config.app_secret = ENV['APP_SECRET']
#
config.app_secret = 'qwSEmWdixdHgwOgXiLdGJt87b9TxMq009gbJWn0fOTygfIk6fAIlgHO9tAPbA4vaKgY'
###############
# Log Filtering
###############
# Data updates from the client come in via Tasks. The task dispatcher logs all calls to tasks.
# By default hashes in the arguments can be filtered based on keys. So any hash with a key of
# password will be filtered. You can add more fields to filter below:
config.filter_keys = [:password]
##########
# Database
##########
# Database config all start with db_ and can be set either in the config
# file or with an environment variable (DB_NAME for example).
# config.db_driver = 'mongo'
# config.db_name = (config.app_name + '_' + Volt.env.to_s)
# config.db_host = 'localhost'
# config.db_port = 27017
#####################
# Compression options
#####################
# If you are not running behind something like nginx in production, you can
# have rack deflate all files.
# config.deflate = true
#######################
# Public configurations
#######################
# Anything under config.public will be sent to the client as well as the server,
# so be sure no private data ends up under public
# Use username instead of email as the login
# config.public.auth.use_username = true
#####################
# Compression Options
#####################
# Disable or enable css/js compression. Default is to only run in production.
# if Volt.env.production?
# config.compress_javascript = true
# config.compress_css = true
# end
################
# Mailer options
################
# The volt-mailer gem uses pony (https://github.com/benprew/pony) to deliver e-mail. Any
# options you would pass to pony can be setup below.
# NOTE: The from address is setup at the top
# Normally pony uses /usr/sbin/sendmail if one is installed. You can specify smtp below:
# config.mailer.via = :smtp
# config.mailer.via_options = {
# :address => 'smtp.yourserver.com',
# :port => '25',
# :user_name => 'user',
# :password => 'password',
# :authentication => :plain, # :plain, :login, :cram_md5, no auth by default
# :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
# }
#############
# Message Bus
#############
# Volt provides a "Message Bus" out of the box. The message bus provides
# a pub/sub service between any volt instance (server, client, runner, etc..)
# that share the same database. The message bus can be used by app code. It
# is also used internally to push data to any listening clients.
#
# The default message bus (called "peer_to_peer") uses the database to sync
# socket ip's/ports.
# config.message_bus.bus_name = 'peer_to_peer'
#
# Encrypt message bus - messages on the message bus are encrypted by default
# using rbnacl.
# config.message_bus.disable_encryption = true
#
# ## MessageBus Server -- the message bus binds to a port and ip which the
# other volt instances need to be able to connect to. You can customize
# the server below:
#
# Port range - you can specify a range of ports that an instance can bind the
# message bus on. You can specify a range, an array of Integers, or an array
# of ranges.
# config.message_bus.bind_port_ranges = (58000..61000)
#
# Bind Ip - specifies the ip address the message bus server should bind on.
# config.message_bus.bind_ip = '127.0.0.1'
#############
# Concurrency
#############
# Volt provides a thread worker pool for incoming task requests (and all
# database requests, since those use tasks to do their work.) The following
# lets you control the size of the worker pool. Threads are only created as
# needed, and are removed after a certain amount of inactivity.
# config.min_worker_threads = 1
# config.max_worker_threads = 10
#
# You can also specify the amount of time a Task should run for before it
# timeout's. Setting this to short can cause unexpected results, currently
# we recomend it be at least 10 seconds.
# config.worker_timeout = 60
end

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<%# IMPORTANT: Please read before changing! %>
<%# This file is rendered on the server using ERB, so it does NOT use Volt's %>
<%# normal template system. You can add to it, but keep in mind the template %>
<%# language difference. This file handles auto-loading all JS/Opal and CSS. %>
<head>
<meta charset="UTF-8" />
<%= javascript_tags %>
<%= css_tags %>
</head>
<body>
</body>
</html>

View File

@ -1,6 +0,0 @@
# Specify which components you wish to include when
# the "home" component loads.
Opal.use_gem("salama-reader")
Opal.use_gem("salama-object-file")

View File

@ -1,10 +0,0 @@
# Place any code you want to run when the component is included on the client
# or server.
# To include code only on the client use:
# if RUBY_PLATFORM == 'opal'
#
# To include code only on the server, use:
# unless RUBY_PLATFORM == 'opal'
# ^^ this will not send compile in code in the conditional to the client.
# ^^ this include code required in the conditional.

View File

@ -1,2 +0,0 @@
Opal.use_gem "salama"
Opal.use_gem "salama-arm"

View File

@ -1,7 +0,0 @@
# See https://github.com/voltrb/volt#routes for more info on routes
client '/about', action: 'about'
# The main route, this should be last. It will match any params not
# previously matched.
client '/', {}

12
index.html.erb Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<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>
<body>
<%= javascript_include_tag "debugger" %>
</body>
</html>

19
lib/base/constant_view.rb Normal file
View File

@ -0,0 +1,19 @@
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
end

90
lib/base/element_view.rb Normal file
View File

@ -0,0 +1,90 @@
# 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
@element = nil
end
#abstract function that should return the single element that is being represented
# the element is also stored in @element
def draw
raise "implement me to return an Element"
end
# helper function to create an element with possible classes, id and text
# The first argument is a bit haml inspired, so "tagname.classname" is the format
# but if tagname is ommited it will default to div
# also several classnames may be given
# if one of the names ends in a ! (bang) it will be assigned as the id
# 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)
name , clazz = name_class.split(".")
name = "div" if name.empty?
element = $document.create_element(name)
element.text = text if text
return element unless clazz
if( clazz.is_a? Array )
clazz.each { |c| add_class_or_id( element , cl )}
else
add_class_or_id element , clazz
end
element
end
def add_class_or_id element , class_or_id
return element unless class_or_id
if class_or_id[-1] == "!"
element.id = class_or_id[0 ... -1]
else
element.add_class class_or_id
end
element
end
# wrap the @element variable with the given element
# so if wrapper == <h4/> the new @element will be <h4> old @element </h4>
# return the new @element, which is wrapper
def wrap_element wrapper
@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>whatever was in there</button> <div>
def wrap_node_with node , wrapper
node.replace_with(wrapper) if node.parent
wrapper << node
end
# add the given element to the @element, at the end
# return the div that was passed in (use << to return the @element)
def append_element div
@element << div
div
end
# add the given element to the @element , at the front
# return the div that was passed in (use >> to return the @element)
def prepend_element div
@element >> div
div
end
# create a new element with class and possibly text
# add that new element to the @element
# return the newly created element
def add class_or_id , tex = nil
append_element div( class_or_id , tex)
end
end

74
lib/base/list_view.rb Normal file
View File

@ -0,0 +1,74 @@
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
@children = children
@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
# return (as per base class) the single root of the collection
def draw root = "div"
@element = div(root)
@elements = @children.collect do | c |
append_element c.draw
end
@element
end
# 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 replaced in the live dom
def replace_at( index , node)
old = @elements[index]
@children[index] = node
rendered = node.draw
@elements[index] = rendered
old.replace_with(rendered) if old
end
# remove the first child and element (from view)
def remove_first
remove_at 0
end
# remove both child and element at given position
def remove_at index
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 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
# render it and append it to the html element
# and keep a copy in @elements
def append_view view
@children << view
rendered = view.draw
@elements << rendered # add to internal array
@element << rendered # add to html children
rendered
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)

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

69
lib/views/ref_view.rb Normal file
View File

@ -0,0 +1,69 @@
class RefView < ListView
def initialize name , value , z = nil
@name = name
@value = value
@z = z
super []
end
attr_reader :value
def value= val
@value = val
add_hover
end
def draw
@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?( )
return false if @value.is_a?(Fixnum)
return false unless @value
! is_label?
end
def is_string?()
@value.is_a? String
end
def is_label?
@value.is_a?(Risc::Label)
end
def is_nil?()
@value.nil?
end
def hover
#puts "hovering #{@name}"
append_view ObjectView.new(@value)
@element.off("hover")
end
def marker
if is_string?
str = @value
elsif is_object?
str = Risc::Position.get(@value).to_s
elsif is_label?
str = "Label"
else
str = @value.to_s
end
end
end

View File

@ -0,0 +1,54 @@
require_relative "object_view"
class RegistersView < ListView
def initialize interpreter
@interpreter = interpreter
@interpreter.register_event(:register_changed, self)
kids = []
@interpreter.registers.each do |reg , val|
kids << ValueView.new( val )
end
super(kids)
end
def draw
super( "div.registers_view" )
@element.children.each_with_index do |reg, index|
elem = div("div.register_view")
wrap_node_with reg , elem
end
@element
end
def register_changed( reg , old , value )
reg = reg.symbol unless reg.is_a? Symbol
index = reg.to_s[1 .. -1 ].to_i
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
replace_at index , swap
# @elements[index].style["z-index"] = -index
end
end
class ValueView < ElementView
def initialize value
@value = value
end
def draw
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 '', type: :feature do
# Specs here
end

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 375 KiB