From 539b7d9cfe601a4891b6fa959916cf80b5953651 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 9 Apr 2018 22:23:28 +0300 Subject: [PATCH] new hello world post --- Gemfile.lock | 150 ++++++++++++--------- _posts/2018-04-09-a-dynamic-hello-world.md | 95 +++++++++++++ 2 files changed, 185 insertions(+), 60 deletions(-) create mode 100644 _posts/2018-04-09-a-dynamic-hello-world.md diff --git a/Gemfile.lock b/Gemfile.lock index a227579..1a1b2a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,34 +13,42 @@ GEM execjs coffee-script-source (1.11.1) colorator (1.1.0) + commonmarker (0.17.9) + ruby-enum (~> 0.5) concurrent-ruby (1.0.5) + em-websocket (0.5.1) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0.6.0) ethon (0.11.0) ffi (>= 1.3.0) + eventmachine (1.2.5) execjs (2.7.0) - faraday (0.13.1) + faraday (0.14.0) multipart-post (>= 1.2, < 3) - ffi (1.9.18) + ffi (1.9.23) forwardable-extended (2.6.0) gemoji (3.0.0) - github-pages (168) + github-pages (180) activesupport (= 4.2.9) - github-pages-health-check (= 1.3.5) - jekyll (= 3.6.2) + github-pages-health-check (= 1.4.0) + jekyll (= 3.7.3) jekyll-avatar (= 0.5.0) - jekyll-coffeescript (= 1.0.2) + jekyll-coffeescript (= 1.1.1) + jekyll-commonmark-ghpages (= 0.1.5) jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.9.2) - jekyll-gist (= 1.4.1) - jekyll-github-metadata (= 2.9.3) - jekyll-mentions (= 1.2.0) - jekyll-optional-front-matter (= 0.2.0) + jekyll-feed (= 0.9.3) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.9.4) + jekyll-mentions (= 1.3.0) + jekyll-optional-front-matter (= 0.3.0) jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.1.0) - jekyll-redirect-from (= 0.12.1) - jekyll-relative-links (= 0.5.1) - jekyll-sass-converter (= 1.5.0) - jekyll-seo-tag (= 2.3.0) - jekyll-sitemap (= 1.1.1) + jekyll-readme-index (= 0.2.0) + jekyll-redirect-from (= 0.13.0) + jekyll-relative-links (= 0.5.3) + jekyll-remote-theme (= 0.2.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.4.0) + jekyll-sitemap (= 1.2.0) jekyll-swiss (= 0.4.0) jekyll-theme-architect (= 0.1.0) jekyll-theme-cayman (= 0.1.0) @@ -55,69 +63,84 @@ GEM jekyll-theme-slate (= 0.1.0) jekyll-theme-tactile (= 0.1.0) jekyll-theme-time-machine (= 0.1.0) - jekyll-titles-from-headings (= 0.4.0) - jemoji (= 0.8.1) - kramdown (= 1.14.0) + jekyll-titles-from-headings (= 0.5.1) + jemoji (= 0.9.0) + kramdown (= 1.16.2) liquid (= 4.0.0) - listen (= 3.0.6) + listen (= 3.1.5) mercenary (~> 0.3) - minima (= 2.1.1) + minima (= 2.4.0) + nokogiri (>= 1.8.1, < 2.0) rouge (= 2.2.1) terminal-table (~> 1.4) - github-pages-health-check (1.3.5) + github-pages-health-check (1.4.0) addressable (~> 2.3) net-dns (~> 0.8) octokit (~> 4.0) public_suffix (~> 2.0) - typhoeus (~> 0.7) + typhoeus (~> 1.3) html-pipeline (2.7.1) activesupport (>= 2) nokogiri (>= 1.4) - i18n (0.9.1) + http_parser.rb (0.6.0) + i18n (0.9.5) concurrent-ruby (~> 1.0) - jekyll (3.6.2) + jekyll (3.7.3) addressable (~> 2.4) colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 0.7) jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 1.1) + jekyll-watch (~> 2.0) kramdown (~> 1.14) liquid (~> 4.0) mercenary (~> 0.3.3) pathutil (~> 0.9) - rouge (>= 1.7, < 3) + rouge (>= 1.7, < 4) safe_yaml (~> 1.0) jekyll-avatar (0.5.0) jekyll (~> 3.0) - jekyll-coffeescript (1.0.2) + jekyll-coffeescript (1.1.1) coffee-script (~> 2.2) coffee-script-source (~> 1.11.1) + jekyll-commonmark (1.2.0) + commonmarker (~> 0.14) + jekyll (>= 3.0, < 4.0) + jekyll-commonmark-ghpages (0.1.5) + commonmarker (~> 0.17.6) + jekyll-commonmark (~> 1) + rouge (~> 2) jekyll-default-layout (0.1.4) jekyll (~> 3.0) - jekyll-feed (0.9.2) + jekyll-feed (0.9.3) jekyll (~> 3.3) - jekyll-gist (1.4.1) + jekyll-gist (1.5.0) octokit (~> 4.2) - jekyll-github-metadata (2.9.3) + jekyll-github-metadata (2.9.4) jekyll (~> 3.1) octokit (~> 4.0, != 4.4.0) - jekyll-mentions (1.2.0) + jekyll-mentions (1.3.0) activesupport (~> 4.0) html-pipeline (~> 2.3) jekyll (~> 3.0) - jekyll-optional-front-matter (0.2.0) + jekyll-optional-front-matter (0.3.0) jekyll (~> 3.0) jekyll-paginate (1.1.0) - jekyll-readme-index (0.1.0) + jekyll-readme-index (0.2.0) jekyll (~> 3.0) - jekyll-redirect-from (0.12.1) + jekyll-redirect-from (0.13.0) jekyll (~> 3.3) - jekyll-relative-links (0.5.1) + jekyll-relative-links (0.5.3) jekyll (~> 3.3) - jekyll-sass-converter (1.5.0) + jekyll-remote-theme (0.2.3) + jekyll (~> 3.5) + rubyzip (>= 1.2.1, < 3.0) + typhoeus (>= 0.7, < 2.0) + jekyll-sass-converter (1.5.2) sass (~> 3.4) - jekyll-seo-tag (2.3.0) + jekyll-seo-tag (2.4.0) jekyll (~> 3.3) - jekyll-sitemap (1.1.1) + jekyll-sitemap (1.2.0) jekyll (~> 3.3) jekyll-swiss (0.4.0) jekyll-theme-architect (0.1.0) @@ -160,40 +183,47 @@ GEM jekyll-theme-time-machine (0.1.0) jekyll (~> 3.5) jekyll-seo-tag (~> 2.0) - jekyll-titles-from-headings (0.4.0) + jekyll-titles-from-headings (0.5.1) jekyll (~> 3.3) - jekyll-watch (1.5.0) - listen (~> 3.0, < 3.1) - jemoji (0.8.1) + jekyll-watch (2.0.0) + listen (~> 3.0) + jemoji (0.9.0) activesupport (~> 4.0, >= 4.2.9) gemoji (~> 3.0) html-pipeline (~> 2.2) - jekyll (>= 3.0) - kramdown (1.14.0) + jekyll (~> 3.0) + kramdown (1.16.2) liquid (4.0.0) - listen (3.0.6) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9.7) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) mercenary (0.3.6) mini_portile2 (2.3.0) - minima (2.1.1) - jekyll (~> 3.3) - minitest (5.10.3) + minima (2.4.0) + jekyll (~> 3.5) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.11.3) multipart-post (2.0.0) net-dns (0.8.0) - nokogiri (1.8.1) + nokogiri (1.8.2) mini_portile2 (~> 2.3.0) - octokit (4.7.0) + octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) - pathutil (0.16.0) + pathutil (0.16.1) forwardable-extended (~> 2.6) public_suffix (2.0.5) - rb-fsevent (0.10.2) + rb-fsevent (0.10.3) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) rouge (2.2.1) + ruby-enum (0.7.2) + i18n + ruby_dep (1.5.0) + rubyzip (1.2.1) safe_yaml (1.0.4) - sass (3.5.3) + sass (3.5.6) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) @@ -204,9 +234,9 @@ GEM terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) thread_safe (0.3.6) - typhoeus (0.8.0) - ethon (>= 0.8.0) - tzinfo (1.2.4) + typhoeus (1.3.0) + ethon (>= 0.9.0) + tzinfo (1.2.5) thread_safe (~> 0.1) unicode-display_width (1.3.0) diff --git a/_posts/2018-04-09-a-dynamic-hello-world.md b/_posts/2018-04-09-a-dynamic-hello-world.md new file mode 100644 index 0000000..1c112df --- /dev/null +++ b/_posts/2018-04-09-a-dynamic-hello-world.md @@ -0,0 +1,95 @@ +--- +layout: news +author: Torsten +--- + +Now that i *have* had time to write some more code (250 commits last month), here is +the good news: + +## Sending is done + +A dynamic language like ruby really has at it's heart the dynamic method resolution. Without +that we'd be writing C++. Not much can be done in ruby without looking up methods. + +Yet all this time i have been running circles around this mother of a problem, because +(after all) it is a BIG one. It must be the one single most important reason why dynamic +languages are interpreted and not compiled. + +## A brief recap + +Last year already i started on a rewrite. After hitting this exact same wall for the fourth +time. I put in some more Layers, the way a good programmer fixes any daunting problem. + +The [Readme](https://github.com/ruby-x/rubyx) has quite a good summary on the new layers, +and off course i'll update the architecture soon. But in case you didn't click, here is the +very very short summary: + + +- Vool is a Virtual Object Oriented Language. Virtual in that is has no own syntax. But + it has semantics, and those are substantially simpler than ruby. Vool is Ruby without + the fluff. + +- Mom, the Minimal Object Machine layer is the first machine layer. Mom has no concept of memory + yet, only objects. Data is transferred directly from object + to object with one of Mom's main instructions, the SlotLoad. + +- Risc layer here abstracts the Arm in a minimal and independent way. It does not model + any real RISC cpu instruction set, but rather implements what is needed for rubyx. + +- There is a minimal *Arm* translator that transforms Risc instructions to Arm instructions. + Arm instructions assemble themselves into binary code. A minimal *Elf* implementation is + able to create executable binaries from the assembled code and Parfait objects. + +- Parfait: Generating code (by descending above layers) is only half the story in an oo system. + The other half is classes, types, constant objects and a minimal run-time. This is + what is Parfait is. + +## Compiling and building + +After having finished all this layering work, i was back to square *resolve*: how to +dynamically, at run-time, resolve a method to binary. The strategy was going to be to have +some short risc based check and bail out to a method. + +But off course when i got there i started thinking that the resolve method (in ruby) +would need resolve itself. And after briefly considering cheating (hardcoding type +information into this *one* method), i opted to write the code in Risc. Basically assembler. + +And it was horrible. It worked, but it was completely unreadable. So then i wrote a dsl for +generating risc instructions, using a combination of method_missing, instance_eval and +operator overloading. The result is quite readable code, a mixture between assembler and +a mathematical notation, where one can just freely name registers and move data around +with *[]* and *<<*. + +By then resolving worked, but it was still a method. Since it was already in risc, i basically +inlined the code by creating a new Mom instruction and moving the code to it's *to_risc*. +Now resolving still worked, and also looked good. + +A small bug in calling the resulting method was fixed, and *voila*, ruby-x can dynamically call +any method. + +## The proof + +Previous, static, Hello Worlds looked like this: +> "Hello world".putstring + +Off course we can know the type that putstring applies to and so this does not +involve any method resolution at runtime, only at compile time. + +Todays step is thus: +> a = "Hello World" + +> a.putstring + +This does involve a run-time lookup of the *putstring* method. It being a method on String, +it is indeed found and called.(1) Hurray. + +And maths works too: +> a = 150 + +> a.div10 + +Does indeed result in 15. Even with the *new* integers. Part of the rewrite was to upgrade +integers to first class objects. + +PS(1): I know with more analysis the compiler *could* now that *a* is a String (or Integer), +but just now it doesn't. Take my word for it or even better, read the code.