Skip to content

Commit

Permalink
Add experimental reason compiler. Rename generators directory to comp…
Browse files Browse the repository at this point in the history
…iler
  • Loading branch information
dabbott committed Dec 5, 2017
1 parent a48a161 commit f6d84f4
Show file tree
Hide file tree
Showing 54 changed files with 2,914 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -118,7 +118,7 @@ Then choose a directory path:

> Very very experimental. Likely won't generate usable code in its current state
Run the script in `generators/react` on a Lona workspace, e.g:
Run the script in `compiler/react` on a Lona workspace, e.g:

`node index.js [my_workspace_path] output`

Expand Down
8 changes: 8 additions & 0 deletions compiler/core/.gitignore
@@ -0,0 +1,8 @@
.DS_Store
.merlin
.bsb.lock
npm-debug.log
/lib/bs/
/node_modules/

.ninja_log
18 changes: 18 additions & 0 deletions compiler/core/README.md
@@ -0,0 +1,18 @@
# Basic Reason Template

Hello! This project allows you to quickly get started with Reason and BuckleScript. If you wanted a more sophisticated version, try the `react` template (`bsb -theme react -init .`).

# Build
```
npm run build
```

# Build + Watch

```
npm run watch
```


# Editor
If you use `vscode`, Press `Windows + Shift + B` it will build automatically
15 changes: 15 additions & 0 deletions compiler/core/bsconfig.json
@@ -0,0 +1,15 @@
// This is the configuration file used by BuckleScript's build system bsb. Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
// BuckleScript comes with its own parser for bsconfig.json, which is normal JSON, with the extra support of comments and trailing commas.
{
"name": "lona-compiler-core",
"version": "0.1.0",
"sources": ["src"],
"package-specs": {
"module": "commonjs",
"in-source": true
},
"suffix": ".bs.js",
"bs-dependencies": ["bs-node", "bs-json", "bs-batteries"],
"namespace": true,
"refmt": 3
}
20 changes: 20 additions & 0 deletions compiler/core/package.json
@@ -0,0 +1,20 @@
{
"name": "lona-compiler-core",
"version": "0.1.0",
"scripts": {
"build": "bsb -make-world",
"start": "bsb -make-world -w",
"clean": "bsb -clean-world"
},
"keywords": ["BuckleScript"],
"author": "",
"license": "MIT",
"devDependencies": {
"bs-platform": "^2.1.0"
},
"dependencies": {
"bs-batteries": "0.0.14",
"bs-json": "^0.2.4",
"bs-node": "github:buckletypes/bs-node"
}
}
196 changes: 196 additions & 0 deletions compiler/core/src/ast.bs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 93 additions & 0 deletions compiler/core/src/ast.re
@@ -0,0 +1,93 @@
module JavaScript = {
type binaryOperator =
| Eq
| Neq
| Gt
| Gte
| Lt
| Lte
| Plus
| Noop;
type node =
| Return(node)
| Literal(Types.lonaValue)
| Identifier(list(string))
| Class(string, option(string), list(node))
| Method(string, list(string), list(node))
| CallExpression(node, list(node))
| JSXAttribute(string, node)
| JSXElement(string, list(node), list(node))
| VariableDeclaration(node)
| AssignmentExpression(node, node)
| BooleanExpression(node, binaryOperator, node)
| ConditionalStatement(node, list(node))
| ArrayLiteral(list(node))
| ObjectLiteral(list(node))
| ObjectProperty(node, node)
| Block(list(node))
| Program(list(node))
| Unknown;
/* Children are mapped first */
let rec map = (f, node) =>
switch node {
| Return(value) => f(Return(value |> map(f)))
| Literal(_) => f(node)
| Identifier(_) => f(node)
| Class(a, b, body) => f(Class(a, b, body |> List.map(map(f))))
| Method(a, b, body) => f(Method(a, b, body |> List.map(map(f))))
| CallExpression(value, body) => f(CallExpression(value |> map(f), body |> List.map(map(f))))
| JSXAttribute(a, value) => f(JSXAttribute(a, value |> map(f)))
| JSXElement(a, attributes, body) =>
f(JSXElement(a, attributes |> List.map(map(f)), body |> List.map(map(f))))
| VariableDeclaration(value) => f(VariableDeclaration(value |> map(f)))
| AssignmentExpression(value1, value2) =>
f(AssignmentExpression(value1 |> map(f), value2 |> map(f)))
| BooleanExpression(value1, a, value2) =>
f(BooleanExpression(value1 |> map(f), a, value2 |> map(f)))
| ConditionalStatement(condition, body) =>
f(ConditionalStatement(condition |> map(f), body |> List.map(map(f))))
| ArrayLiteral(body) => f(ArrayLiteral(body |> List.map(map(f))))
| ObjectLiteral(body) => f(ObjectLiteral(body |> List.map(map(f))))
| ObjectProperty(value1, value2) => f(ObjectProperty(value1 |> map(f), value2 |> map(f)))
| Block(body) => f(Block(body |> List.map(map(f))))
| Program(body) => f(Program(body |> List.map(map(f))))
| Unknown => f(node)
};
/* Takes an expression like `a === true` and converts it to `a` */
let optimizeTruthyBooleanExpression = (node) => {
let booleanValue = (sub) =>
switch sub {
| Literal(Types.Value(_, value)) => value |> Json.Decode.optional(Json.Decode.bool)
| _ => (None: option(bool))
};
switch node {
| BooleanExpression(a, cmp, b) =>
let boolA = booleanValue(a);
let boolB = booleanValue(b);
switch (boolA, cmp, boolB) {
| (_, Eq, Some(true)) => a
| (Some(true), Eq, _) => b
| _ => node
}
| _ => node
}
};
/* Renamed "layer.View.backgroundColor" to something JS-safe and nice looking */
let renameIdentifiers = (node) =>
switch node {
| Identifier([head, ...tail]) =>
switch head {
| "parameters" => Identifier(["this", "props", ...tail])
| "layers" =>
switch tail {
| [second, ...tail] =>
Identifier([tail |> List.fold_left((a, b) => a ++ "$" ++ b, second)])
| _ => node
}
| _ => node
}
| _ => node
};
let optimize = (node) => node |> map(optimizeTruthyBooleanExpression);
let prepareForRender = (node) => node |> map(renameIdentifiers);
};

0 comments on commit f6d84f4

Please sign in to comment.