degory / ghul Goto Github PK
View Code? Open in Web Editor NEWcompiler for the ghūl programming language
Home Page: https://ghul.dev
License: GNU Affero General Public License v3.0
compiler for the ghūl programming language
Home Page: https://ghul.dev
License: GNU Affero General Public License v3.0
new SOME_CLASS[S,T,U](args)
Rewrite AST in-place and/or rewrite to copy.
Delegate tree walk to nodes where possible.
How to deal with nodes that change type when rewritten? Should we/will we be forced to relax static typing of child nodes within parents?
Adequate mechanism for managing a mix of source files in both new and legacy syntax, in case I need to fall back to work around issues in the new compile (maybe subsumed under #33)
parse break
and continue
statements, with + without loop labels
parse expressions supporting same set of operators with same precedence as old L syntax
Separate sub-visitors for sub-types of AST with useful pluggable default behaviours - e.g. skip unhandled subtrees entirely, or walk unknown subtrees picking up again where recognized. Delegate walking subtrees to node classes to avoid duplicating in every visitor (not suitable for pretty printer as order depends on nodes, but likely applicable to future visitors)
use some.namespace;
use some.namespace.symbol;
trying to avoid need for this stuff in the first place, and instead to use conventions instead. however, in short term, me something we can translate from ghul to L with no symbol table or understanding of semantics.
place access modifiers and/or storage classes after colon and before type
property: int private static;
constant: int const = 50;
parse while
-do
-od
statements
parse do
-od
statements
Need to determine how to generate the parser.
Options are:
parse if-then-elif-fi
Need complete grammar for language that can be compiled in to a parser
static member access on generic classes is ambiguous with array/indexer access:
Util.Sort[String].sort(["a", "b", "c"]);
some.variable[a_string].sort(["a", "b", "c"]
options include
[]
ref
ptr
?
), and the primary parser would need to accept built in types as expression primaries.[
always unambiguously introduces an indexer accesssome_class::static_member
Util::Sort[String]::sort(["a", "b", "c"])
.Util.Sort[String]::sort(["a", "b", "c"])
want to be able to apply some higher level optimisations, such as devirtualization, that require the compiler prove certain values only ever hold specific types or a subset of possible types, or are not changed across a particular call or code block. In addition, some of this information can be passed to LLVM to aid in its alias analysis.
need a framework that to support this analysis.
parse case
-when
-default
-esac
statements
case a
when x: do_x();
when y: do_y();
default: do_something_else();
esac
parse has-value operator value?
parse function definitions
some_function(a: int, b: int) -> int => a + b;
other_function(a: int, b: int) -> int is return a - b; si
some mechanism to avoid changing timestamps on generated files if they're not changed - maybe via hashing of content.
alter format of error output from old compiler in line with new, so same VS Code problem match regex will work across both sources of errors
some kind of compiler driver to run the old compiler on the generated output, and merge error reports in with errors from new parser - shell scripts may be sufficient
var a: int?;
if a? then
...
fi
?
operator should bind more tightly than prefix unary operators
x: int?;
y: String?;
Ultimately want nullable-ness to be opt-in across all value and reference types and all accesses through nullables to require a preceding successful has-value operation (?
), provable via data-flow analysis.
Can't implement this until we have a real middle-end - even foregoing the data-flow analysis, we cannot determine what legacy L to emit without symbol type information, as required behaviour would differ for value types vs reference types (value types need wrapping in a struct, with a has-value flag, reference types can stay as is, with null representing has-no-value)
Not sure in the interim that there's much point in bothering to parse this?
Need to be able to transform an input stream from bytes/characters into tokens
cast SOME_TYPE(expression)
some means of automated regression testing
support parsing namespaces:
namespace Something is
...
si
should also support qualified names, e.g.
namespace Syntax.Parser is
...
si
Fix indentation and spacing
Consider inserting line breaks and indentation in complex expressions.
Add support for producing HTML markup:
For website, call compiler on fly to render code examples for detected with - expose an AJAX service that can format any code snippet from its server-side file name (obviously needs to be done securely so can't be used to read arbitrary files from the server, probably by doing a lookup through a white-list table to the real file name)
parse return
statements, with + without a return value
parse try
-catch
-finally
-yrt
semicolons are missing at least after definitions and maybe elsewhere
When it comes to bootstrap the new compiler, I do not want to manually translate new compiler source from old L language syntax to new language - there could be tens of thousands of lines.
To avoid doing this, I can use the new compiler to translate new language syntax to old.
New syntax source -> [New compiler] -> Old syntax -> [Old compiler] -> Executable
Provided the new compiler is written in a subset of the new language where the new syntax maps directly onto the old syntax with the same semantics, this can be accomplished with a pretty printer.
Required:
Nice to have:
Once this mechanism is in place, hand translate the new compiler to the new syntax, and all new development can be done in the new syntax.
Compiler should be capable of building itself
new language needs a name:
parser does not accept properties with neither read or assign body, for example:
a;
b: int;
support parsing` properties
prop: int; // auto property, public read, private assign
_prop: int; // private field
prop: int
=> _some_field,
= value is _some_field = value; si
support parsing readable and assignable indexers
class INDEXABLE is
elements: int[];
[index: int]: int
=> elements[index],
= value is
elements[index] = value;
si
si
enum SUITS is
CLUBS,
DIAMONDS,
HEARTS,
SPADES
si
enum BITS is
ONE = 1 << 0,
TWO = 1 << 1,
THREE = 1 << 2,
FOUR = 1 << 3
si
parse labels for loops, for targetted break and continue statements.
some_label: for i in list do
break some_label;
od
parse assignment statements.
Consider destructuring assign, e.g.
a, b, d, e = (a, (b, c), d);
x, y = y, x;
However, may not be straightforward to dumb-translate this into L old syntax (might require temporary variables)
parse list literals
[a, b, c, d]
[[x, y], [z, w]]
["a", b, c]: System.Object
need to support an optional explicit element type, at least until bootstrapped, because the legacy compiler's type inference for list literals is not 100% reliable
support assignable and writable indexed properties
class DOUBLE_THINGS is
elements: int[];
single_things[index: int]: int
=> elements[index],
= value is
elements[index] = value;
si
double_things[index: int]: int
=> elements[index] * 2,
= value is
elements[index] = value / 2;
si
si
parse statements that are an arbitrary expression
statement will be a foreach, i.e. new syntax
for i in 0..9 do
IO.Std.err.println("blah");
od
is equivalent to old L syntax
foreach var i; 0..9 do
IO.Std.err.println("blah");
od
Note
var
- loop variable is auto-declared let
, scoped to body of loopparse while-do-od
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.