Skip to content

Instantly share code, notes, and snippets.

@ELLIOTTCABLE
Created February 19, 2010 19:37
Show Gist options
  • Save ELLIOTTCABLE/309103 to your computer and use it in GitHub Desktop.
Save ELLIOTTCABLE/309103 to your computer and use it in GitHub Desktop.
- Multiple frameworks in Paws.o:
- Object system: Provides data types and ‘object’ APIs; handles internal
interactions between items in the ‘world,’ such as lookups
- Interpreter: Handles ‘worlds,’ specifically, ‘interpretation units.’
Comprises the garbage collection system, IU federation/
networking components, the routine-threading model, and (of
course) the actual procedural AST interpreter.
- Parser: Comprises the lexer and parser, and provides APIs to access and
modify the AST. Handles conversion of a I/O stream to a token
stream, and subsequently conversion of that token stream to an
AST. Must provide intermediate stages for the final portion…
- Preprocessor: Responsible for turning a Paws document (with operators,
macros, constants, and such) into a µPaws document (sans
operators, consisting entirely of routine literals and word
lists)
Provided binaries:
- `paws`, a combination wrapper for all of the above stages: takes a full-on
Paws source file, preprocesses it, and interprets the result.
- `ppaws` (the ‘Preprocessor for Paws’), a direct interface to the
preprocessor and parser portions. Takes a full-on Paws source file, and
spits out a valid µPaws document, with all operators and macros handled out
- `upaws`, the C interpreter itself, a direct interface to the parser,
interpreter, and object system. Expects a µPaws document; will not invoke
the preprocessor, and thus will not properly handle operators or macros.
Can expect in the future:
- `lassie`, a REPL-on-steroids… more accurately, an interactive interpreter
tied to an object system interrogator
- `cpaws`, a bytecode-compiler to Paws objects
- `vpaws`, a bytecode-VM for Paws objects
Preprocessor details:
- Since there are no comments, nor illegal characters in names, we have to use
valid names as our preprocessor directives. This has the side effect of
making our un-preprocessed Paws files valid µPaws files… they simply won’t
execute as expected (given that there will probably be a lot of weird,
unexpected lookups.)
- Most likely, use ‘magic strings,’ since that’s how comments normally work.
Again, a side effect of making the preprocessor directives accessible from
the processed µPaws, if a library author really wants to grab them for some
reason.
Macro example:
“=macro ‘FOO BAR’ baz”;
“ The following will become `something baz something.else`: ”;
something FOO BAR something.else
Operators will be defined via preprocessor directives in this format:
`=operator ‘«identifier»’ «arity» [«associativity»] [«priority»] [«expansion»]`
- «identifier» is the word or sentence of source code that will be treated as
an operator
- «arity» is the number of arguments the operator takes (can be a numeral, or
a word following the ‘unary,’ ‘binary,’ ‘ternary’ pattern)
- «associativity» is the direction in which the preprocessor will search for
words to attach the operator to (can be either ‘left,’ ‘right,’ or ‘none’;
defaults to ‘left’)
- «priority» determines how the operator is handled in proximity to other
operators; can be a positive or negative numeric value, with higher (more
numerically positive) values being processed earlier (more ‘inner’). Can be
a numeral; one of ‘low,’ ‘medium,’ ‘high,’ (which correspond to -100, 0,
and +100, respectively); or one of the previous extremes with a number of
instances of the word ‘very,’ which indicates an additional power of ten
(i.e. ‘very very high’ is equivalent to +100e2, or +10,000)
- «expansion», if present, determines an alternative expression that will be
used to resolve the operator
After order/grouping is determined, the preprocessor turns each operator and
its relative expressions into a single ‘indirected lookup’ (usually, actually,
a routine call… but not necessarily) expression, depending upon whether an
expansion was defined for the operator or not.
If no «expression» was defined for an operator, then an operator-lookup is
preformed on the first argument to the operator (which is the ‘first’ argument
is determined by the «associativity»); the rest of the arguments are passed to
the routine call serially: if `foo` has no «expression» and is left-
associative, then `bar foo baz` becomes `bar foo (baz)`, i.e. a call to
`bar`’s `foo` routine, with `baz` as an argument. This means that unary
operators become argument-less function calls: right-«associativity» unary-
«arity» `√` turns `√something` into `something √ ()`.
If an «expression» *is* defined, then it is used in place of that lookup. For
instance, if our `foo` operator *did* define an «expression», let’s say
`a b c`, then our `bar foo baz` would be processed into `a b c (~(bar) ,(baz))`
Operator example:
“=operator ‘+’ binary left medium”;
“=operator ‘√’ unary right high mathematics √”;
“ The following will become `mathematics √ (foo) + (bar)`: ”;
√foo + bar
------------------------------------------------------------------------------
- multiple preprocessor runs
- maintain source information for each preprocessor run-through, and final
interpretation stage
- file, line number
- line index of first character of literal
- nesting level (within routine literals / expressions)
- file/line number/index of each routine/expression? how?
Preprocessor declaration initiators:
¦ operator
::operator (for ASCII compat)
So, preprocessor runs through; every time it sees a processing instruction, it
stores that instruction along with the place it found the instruction.
¦ operator “∫”, “(”, “)” (ternary, postfix, left, medium) “mathematics ∫”
“Becomes `mathematics ∫ (~ (4) , (10) , (foo bar))`:”
4∫10 (foo bar)
¦ operator “?”, “:” (ternary, postfix, left, medium, routine) “infrastructure ?:”
“Becomes `infrastructure ?: (~ {@(foo is.awesome)} , {@(then do)} , {@(else do)})`:”
foo is.awesome ? then do : else do
(Can we somehow declare *individual arguments* that should be routines instead
of values? Turning *every argument* into a routine literal is a bit meh…)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment