Commit Graph

42 Commits (f183ccb2b0719205e63abda363c31daa5fc679c4)

Author SHA1 Message Date
Mike Gerwitz f183ccb2b0
rebirth: Properly `quote' strings
Make sure quoted strings are, well, strings---they need their delimiters!

* build-aux/bootstrap/rebirth.scm (quote-sexp): Proper handling of strings.
2017-12-11 22:26:02 -05:00
Mike Gerwitz c3dec75fe7
birth: Support for cond-expand else
Birth is pretty much at a feature freeze at this point, but `cond-expand'
really was difficult to work with in certain circumstances when it didn't
even support `else'.

* build-aux/bootstrap/birth.scm (fnmap)[cond-expand]: Always expand `else'
    while dropping all others.
2017-12-11 22:24:19 -05:00
Mike Gerwitz f18322fbe5
birth, rebirth: Correct *->ecmascript procedure names
They were just out of date, having been copied from Prebirth.

* build-aux/bootstrap/birth.scm
  (prebirth->ecmascript, birth>ecmascript): Former renamed to latter.
* build-aux/bootstrap/rebirth.scm
  (prebirth->ecmascript, rebirth>ecmascript): Former renamed to latter.
2017-12-09 23:43:33 -05:00
Mike Gerwitz 0f9b034a82
rebirth: Unencapsulate all procedures
Many of the procedures were encapsulated within `prebirth->ecmascript';
these have been moved out so that they can be accessed by other procedures,
allowing me to organize the code how I please.

Which also makes me realize that the procedure name is incorrect.

* build-aux/bootstrap/rebirth.scm: Move all procedures out of
    `prebirth->ecmascript'.
2017-12-09 23:43:22 -05:00
Mike Gerwitz a839301a12
rebirth: Make quote form recursive, add quasiquote
This was pretty much a prerequisite for introducing macros (in commits to
follow)---the code would otherwise be far too verbose.

Note that this does _not_ introduce the shorthand forms ("'", "`", ",",
",@"), as implementing those in a reasonable manner would require
preprocesing the AST, which is not what I want to focus on right now.  So
macros will still be a bit verbose, using the full
"(quasiquote ... (unquote-splicing ...))" and such instead of simply
"`(... ,@(...))"

* build-aux/bootstrap/rebirth.scm
  (quote-sexp, quasiquote-sexp): Add procedures.
  (fnmap)[quote]: Use `quote-sexp'.
    [quasiquote]: Add special form.
2017-12-06 22:48:16 -05:00
Mike Gerwitz d881345fe6
Rebirth Lisp: Liberated from libprebirth
Well, the first iteration of it, anyway.
2017-12-05 00:54:20 -05:00
Mike Gerwitz 4585203a22
rebirth: Remove libprebirth.js dependency
This re-implements libprebirth in Rebirth Lisp, finally cutting the
cord.  (Are these birth puns getting out of control?)  We are finally purely
in Lisp land!

* build-aux/bootstrap/rebirth.scm: Define libprebith primitives when
    `string->es' is available (using `cond-expand').
  (prebirth->ecmascript): Do not include `libprebirth.js' in output.
2017-12-05 00:50:29 -05:00
Mike Gerwitz 7f7a9704e5
prebirth,birth,rebirth: Permit newlines in strings
This modifies each of the three lexers just to avoid confusion, even
though prebirth has no need for it.  Birth does have a need, however, since
rebirth will contain newlines---despite the relevant rebirth code (next
commit) not being expanded, it still has to go through the lexer, which
otherwise errors out.

* build-aux/bootstrap/birth.scm (lex): Permit newlines in string regex.
* build-aux/bootstrap/prebirth.js (lex): Permit newlines in string regex.
* build-aux/bootstrap/rebirth.scm (lex): Permit newlines in string regex.
2017-12-05 00:47:26 -05:00
Mike Gerwitz 639948da02
birth,rebirth: Add cond-expand, string->es
`cond-expand' allows moving forward with implementing features based on the
current bootstrapped state of the system---rebirth will be able to
recursively compile itself and introduce new features along the way.

`string->es' allows outputting raw ECMAScript, which gives us more control
over the code that is generated without having to hard-code it in the
compiler itself.

* build-aux/bootstrap/birth.scm
  (fnmap)[cond-expand]: Always yield the empty string (do nothing).
* build-aux/bootstrap/rebirth.scm
  (fnmap)[cond-expand]: Expand `string->es' only.
  (fnmap)[string->es]: Add macro.
2017-12-05 00:38:39 -05:00
Mike Gerwitz 4702184c33
libprebirth: Remove unused `append!'
* build-aux/bootstrap/libprebirth.js
  ($$append$b$): Remove function.
  ($$append): Fix whitespace.
2017-12-05 00:33:34 -05:00
Mike Gerwitz 53ea5c5f4d
rebirth: Add variable definitions (define)
`define' can now be used to define values in addition to the procedure
short-hand.

* build-aux/bootstrap/rebirth.scm
  (cdfn): New procedure.  Renamed original `cdfn' to `cdfn-proc'.
  (cdfn-var): New procedure.
  (cdfn-proc): Renamed from `cdfn'.
2017-12-05 00:32:40 -05:00
Mike Gerwitz 1810fb7c38
rebirth: Copy from birth.scm
See diff for comments as to why this fork exists.

build-aux/bootstrap/rebirth.scm: New file, copied from `birth.scm'.
2017-11-12 00:53:32 -05:00
Mike Gerwitz 4b14c9097f
birth: Remove XXX about hitting stack limits
That's no longer a problem; missed this comment.

* birth.scm (sexp->es): Remove XXX.
2017-11-12 00:52:45 -05:00
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 d3779c2de6
README.md: Gibbly pupils
This just uses '0' in place of 'O'.

* README.md: Give Gibbly pupils.
2017-10-22 01:16:31 -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 5fca236834
birth: Include pos and window in lexing error
Analog to prelude.js's `Parser#_error'.

* build-aux/bootstrap/birth.scm (parse-error): Add procedure.
  (lex): Use it for string error.
2017-08-31 12:44:41 -04:00
Mike Gerwitz b58bbe3949
prebirth: Add `-' to libprebirth
* build-aux/bootstrap/libprebirth.js ($$$_$): Add function.
2017-08-31 12:43:42 -04:00
Mike Gerwitz 41bf925b4e
prebirth: Add `string-append' to libprebirth
* build-aux/bootstrap/libprebirth.js ($$string$_$append): Add function.
2017-08-31 12:42:25 -04:00
Mike Gerwitz b5f70fd8a6
birth: Add birth.scm, which can parse itself and output a CST
Exciting first step!  Though it required a much more complicated Prebirth
Lisp than I was hoping to create.  And I never intended to go into a full
Scheme implementation, but that's the route this is headed in.  I just can't
stomach creating this full system in a block language.

With that said, the block language will still be able to work with all Lisp
code; you'll see.

* build-aux/bootstrap/birth.scm: Add beginning of Birth, capable of parsing
    itself!  Baby steps!
2017-08-31 01:01:06 -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 f626891e75
prebirth: More substantial libprebirth
This is a decent start.

* build-aux/bootstrap/libprebirth.js: Add a lot of stuff.  Go look for
  yourself.
2017-08-31 00:47:57 -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
Mike Gerwitz ecd8b6d9e7
Add README.md and COPYING 2017-08-21 02:19:36 -04:00