Commit Graph

22 Commits (639948da0201c56505047442d15c72b50f3e3ccc)

Author SHA1 Message Date
Mike Gerwitz 6138731304
bootstrap: Formalize (both command-line and browser)
This allows bootstrapping in either a development environment (Node.js) or
simply using the intended runtime environment: the user's browser.

* bootstrap.html: Add file (browser).
* bootstrap.js: Add file (command-line).
* bootstrap/Bootstrap.js: Add class.  Formalize bootstrap process.
* bootstrap/libprebirth.js
  (fsdata): Add variable to serve as filesystem stub.
  (fs): Always throw error when `fs' module is unavailable.
  ($$js$file$_$$g$string): Consider `fsdata'.
* bootstrap/prebirth.js: Export as CommonJS module if in proper
    environment.  Abort automatic processing via stdin if root CommonJS
    module.
2017-11-12 00:29:40 -05:00
Mike Gerwitz 2e5b536a5d
prebirth: Add Prebirth facade
This provides the complete compiler output, which is consistent with the
output of Birth.  This will be useful for browser-based bootstrapping.

* build-aux/bootstrap/prebirth.js: Extract code into `Prebirth' class and
    use the class.
  (Prebirth): Add class.
2017-10-22 01:17:16 -04:00
Mike Gerwitz 431b18e1df
birth,prebirth: Non-recursive lexing to prevent stack exhaustion
This needs to run in the browser too, where we have no control over stack
limits.

* build-aux/bootstrap/birth.scm
  (lex): Non-recursive strategy (loop with mutable list).
  (make-token): Update doc.  Produce list of token, new string, and
    position.  Don't recurse.
  (body->es): Add `ret' param.  Only produce `return' statement if new param
    is set.
  (cdfn): Use it.
  (fnmap)
    [js:while, js:break]: Add forms.
    [lambda, let, case]: Use new `body->es' `ret' param.
    [let*]: Define JS variables in output using `let' instead of `const' to
      permit mutating with new `set!' form.  Use new `body->es' `ret' param.
    [set!]: Add form.
  (prebirth->ecmascript): Adjust libprebirth path to be relative to self.

* build-aux/bootstrap/libprebirth.js
  ($$append$b$): Add `append!' procedure.
  ($$js$regexp, $$js$match, $$js$replace): Move a few lines up.
  (fs): Provide stub if `require' is not defined.

* build-aux/bootstrap/prebirth.js
  (_lex): Non-recursive strategy (loop with array-appending).
  (_token): No more mutual recursion with `#_lex'.  Return new string
    and position.
  (_bodyToEs): Add `ret' param.  Only produce `return' statement if new
    param is set.
  (fnmap) [js:while, js:break]: Add forms.
    [let*]: Define JS variables in output using `let' instead of `const' to
      permit mutating with new `set!' form.  Use new `body->es' `ret' param.
    [set!]: Add form.
2017-10-18 02:41:43 -04:00
Mike Gerwitz 35fa13a8a0
birth: Prebirth self-hosting
This completes bootstrapping for Prebirth Lisp.  The next step will be
Rebirth, which will replace libprebirth.js, removing hand-written JavaScript
entirely.
2017-10-09 21:22:59 -04:00
Mike Gerwitz a5b53fedf5
prebirth: Add `quote' form
* build-aux/bootstrap/prebirth.js (fnmap): Add `quote' form.
2017-09-21 02:23:05 -04:00
Mike Gerwitz ea7425dc6d
prebirth: Always process identifiers (remove global distinction)
* build-aux/bootstrap/prebirth.js
  (_cdfn): Remove second argument to `#_idFromName'.
  (_idFromName): Remove second parameter `global'.  Identify and echo
    integers.  Remove distinction between global and non-global
    identifiers---process everything.
2017-09-21 02:19:38 -04:00
Mike Gerwitz 3310241a94
birth: AST generation
Just about ready for that sloppy code generation!

* build-aux/bootstrap/birth.scm: Update file header documentation.
  Add some whitespace between existing procedures.
  Invoke `parse-lisp' as the program in place of `lex', producing an AST as
    output to the console.
  (cadddr): Add procedure.
  (token-{type,lexeme,value,pos}): Add procedures.
  (parse-lisp): Add procedure (contains other procedures).
* build-aux/bootstrap/libprebirth.js
  ($$append): Add function (append).
  ($$$_$): Correct implementation (-).
  ($$zero$7$): Add predicate (zero?).
  ($$fold): Add function (fold).
* build-aux/bootstrap/prebirth.js (parseLisp): Lowercase some errors.
  (Compiler): Update class docblock.
  (fnmap)[labmda]: Add `lambda' form.
2017-09-02 01:30:13 -04:00
Mike Gerwitz dd34498808
prebirth: Allow nested defines
This just reorganizes things slightly to allow for nested `define's.  This
is a common means of encapsulation, and will Just Work™ because JS has
pretty much identical block scoping rules in this regard.

* build-aux/bootstrap/prebirth.js (compile): Invoke `#_sexpsToEs' directly
    instead of `#_cdfn' on tree.
  (_cdfn): Remove non-`define' check to proxy to `#_sexpsToEs'.
  (_sexpsToEs): Treat `define' as a special case, invoking `#_cdfn'.
2017-09-02 01:25:31 -04:00
Mike Gerwitz 866139e60a
prebirth: Scheme-like truth test for `if' form
Already implemented by `case', `or', `and'.

* build-aux/bootstrap/prebirth.js (fnmap)[if]: Use proper truth check, as
    expected by RnRS Scheme.  For JS, this means only `false' is non-true.
2017-08-31 00:48:18 -04:00
Mike Gerwitz 512780eafe
prebirth: Add `and', `or', and `case' special forms
So much for simple.  But it's not worth my suffering to not add them.

* build-aux/bootstrap/prebirth.js (fnmap): Add more information to docblock.
  (and, or, case): Add special forms.
2017-08-31 00:48:02 -04:00
Mike Gerwitz fe80b398b5
prebirth: Correct token value parsing
Empty string was not matching, which was causing its value to be '""', which
expanded (in JS) into the compiled string '""""'.  Oops.

* build-aux/bootstrap/prebirth.js (Parser#_token): Distinguish empty values
    from non-matches.
2017-08-30 00:25:43 -04:00
Mike Gerwitz 59daf7a5b5
prebirth: Wrap `if' applications
* build-aux/bootstrap/prebirth.js (fnmap)[if]: Wrap generated code
    in self-executing function.
2017-08-30 00:25:32 -04:00
Mike Gerwitz dcc6aed322
prebirth: Add newlines between body expressions
Just makes it easier to look at for debugging.

* build-aux/bootstrap/prebirth.js (Compiler#_bodyToEs): Add newlines.
2017-08-30 00:00:39 -04:00
Mike Gerwitz ef4f70bf96
prebirth: Initial function map
The Prebirth JS compiler is getting much more sophisticated than I had
hoped, but I need something to work with here.  This starts to get us
in a good spot.

There are other conveniences I will want.  More to come.

* build-aux/bootstrap/prebirth.js
  (Compiler#constructor): Add method, accept fnmap.
  (Compiler#_sexpToEs): Use fnmap as needed.
  (fnmap): Add initial map.
  Instantiate `Compiler' with fnmap.
2017-08-30 00:00:22 -04:00
Mike Gerwitz 61f6ba1470
prebirth: Distinguishable id generation
* build-aux/bootstrap/prebirth.js (Compiler#_idFromName): Distinguish
  between certain types of characters.
2017-08-29 23:59:49 -04:00
Mike Gerwitz 6a736a8fcd
prebirth: Ignore comments in JS parser
* build-aux/bootstrap/prebirth.js (parseLisp): Ingore comment tokens.
  (_lex): Recognize comments.
2017-08-29 01:27:54 -04:00
Mike Gerwitz 3c5089417c
prebirth: Globally unique functions
This was implicit in the `define-block' implementation because of the
conversion from `<foo>' to `$foo$', but that's no longer the case.

This is just a simple, temporary implementation, so don't be alarmed.

* build-aux/bootstrap/libprebirth.js: Updated header documentation to
    mention `$$' prefix.
  ($$js$console): Renamed from `js$console'.
* build-aux/bootstrap/prebirth.js
  (_idFromName): Add `global' parameter to add `$$' prefix to generated
    identifiers.
  (_cdfn, _sexpToEs): Use it.
2017-08-28 23:42:19 -04:00
Mike Gerwitz 19642e59d9
prebirth: Prepend libprebirth to output
* build-aux/bootstrap/libprebirth.js: Add file.
* build-aux/bootstrap/prebirth.js: Prepend `libprebirth.js' contents to
  output.
2017-08-28 01:22:51 -04:00
Mike Gerwitz f2adafb264
prebirth: Allow toplevel function applications
So we can invoke the main function for the program.

* build-aux/bootstrap/prebirth.js
  (Compiler#_cdfn): Handle non-`define' applications.
  (Compiler#assertApply): Remove function.
2017-08-28 01:21:02 -04:00
Mike Gerwitz f23396de2e
prebirth: Abandon `define-block' in favor of `define'
Turns out, I'll kill myself before writing a Prebirth compiler in a
block-define-based Prebirth Lisp.  So, let's degrade even further into a
primitive Scheme.  This is going down a dangerous path to simply
implementing Scheme...

Nonetheless, here I remove `define-block' in favor of a simple shorthand
function definition `define', as is custom in Scheme.  We will worry
about block definitions later as metadata mapping to normal functions.
2017-08-28 00:53:02 -04:00
Mike Gerwitz c0fb8297a6
Prebirth: Add docstring
* build-aux/bootstrap/prebirth.js (Compiler#_docstring): Add method.
  (Compiler#_cdfn): Use it.
2017-08-21 02:39:33 -04:00
Mike Gerwitz 7998296a20
Add prebirth.js
This is hopefully the beginning of a good thing that I'll actually
finish.  I began planning this project formally just before the beginning of
Aug 2017.

* build-aux/bootstrap/prebirth.js: New file.
2017-08-21 02:20:10 -04:00