diff --git a/.gitignore b/.gitignore index 9f912e847..f2bf387b2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,6 @@ node_modules/ # tsc lib/ -# local development files -Makefile - # bolt .bolt-work/ diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..cca378698 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ + +all: lib/ast.js + bolt bundle test.bolt + +lib/ast.js: spec/ast.txt lib/treegen/parser.js lib/bin/bolt-treegen.js lib/treegen/util.js src/treegen/ast-template.js + @echo "Generating AST definitions ..." + @mkdir -p lib/ + @chmod +x lib/bin/*.js + @bolt-treegen --js-file=lib/ast.js --dts-file src/ast.d.ts spec/ast.txt + +lib/treegen/parser.js: src/treegen/parser.pegjs + @echo "Generating parser ..." + @mkdir -p lib/treegen/ + @if ! npx pegjs --output lib/treegen/parser.js src/treegen/parser.pegjs; then \ + rm -rf lib/treegen/parser.js; \ + exit 1; \ + fi + +.PHONY: clean + +clean: + rm -rf lib/treegen/parser.js + rm -rf lib/ast.js + rm -rf src/ast.d.ts + +.PHONY: distclean + +distclean: + rm -rf lib/ + diff --git a/spec/ast.txt b/spec/ast.txt new file mode 100644 index 000000000..20921dd5b --- /dev/null +++ b/spec/ast.txt @@ -0,0 +1,314 @@ + +// Bolt language AST definitions + +type BoltValue = Integer | bool | String; + +node FunctionBody; + +enum BoltDeclarationModifiers { + Mutable = 0x1, + Public = 0x2, + IsType = 0x4, +} + +node BoltToken; + +node BoltStringLiteral > BoltToken { + value: String, +} + +node BoltIntegerLiteral > BoltToken { + value: usize, +} + +node BoltSymbol > BoltToken { + +} + +node BoltIdentifier > BoltSymbol { + text: String, +} + +node BoltOperator > BoltSymbol { + text: String, +} + +node BoltEOS > BoltToken; + +node BoltComma > BoltToken; +node BoltSemi > BoltToken; +node BoltDot > BoltToken; +node BoltDotDot > BoltToken; +node BoltRArrow > BoltToken; +node BoltLArrow > BoltToken; +node BoltEqSign > BoltToken; + +node BoltKeyword; + +node BoltFnKeyword > BoltToken, BoltKeyword; +node BoltForeignKeyword > BoltToken, BoltKeyword; +node BoltLetKeyword > BoltToken, BoltKeyword; +node BoltImportKeyword > BoltToken, BoltKeyword; +node BoltPubKeyword > BoltToken, BoltKeyword; +node BoltModKeyword > BoltToken, BoltKeyword; +node BoltEnumKeyword > BoltToken, BoltKeyword; +node BoltStructKeyword > BoltToken, BoltKeyword; +node BoltNewTypeKeyword > BoltToken, BoltKeyword; + +node BoltPunctuated > BoltToken { + text: String, +} + +node BoltParenthesized > BoltPunctuated; +node BoltBraced > BoltPunctuated; +node BoltBracketed > BoltPunctuated; + +node BoltSourceElement; + +node BoltSourceFile { + elements: Vec, +} + +node BoltQualName { + modulePath: Vec, + name: BoltSymbol, +} + +node BoltTypeNode; + +node BoltReferenceTypeNode > BoltTypeNode { + name: BoltQualName, + arguments: Option>, +} + +node BoltPattern; + +node BoltBindPattern > BoltPattern { + name: String, +} + +node BoltTypePattern > BoltPattern { + typeNode: BoltTypeNode, + nestedPattern: BoltPattern, +} + +node BoltExpressionPattern > BoltPattern { + expression: BoltExpression, +} + +node BoltTuplePatternElement { + index: usize, + pattern: BoltPattern, +} + +node BoltTuplePattern > BoltPattern { + elements: Vec, +} + +node BoltRecordPatternField { + name: BoltIdentifier, + pattern: BoltPattern, +} + +node BoltRecordPattern > BoltPattern { + fields: Vec, +} + +node BoltExpression; + +node BoltCallExpression > BoltExpression { + operator: BoltExpression, + operands: Vec, +} + +node BoltYieldExpression > BoltExpression { + value: BoltExpression, +} + +node BoltMatchArm { + pattern: BoltPattern, + body: BoltExpression, +} + +node BoltMatchExpression > BoltExpression { + value: BoltExpression, + arms: Vec, +} + +node BoltCase { + test: BoltExpression, + result: BoltExpression, +} + +node BoltCaseExpression > BoltExpression { + cases: Vec, +} + +node BoltBlockExpression > BoltExpression { + statements: Vec, +} + +node BoltConstantExpression > BoltExpression { + value: BoltValue, +} + +node BoltStatement; + +node BoltReturnStatement > BoltStatement { + value: Option, +} + +node BoltResumeStatement > BoltStatement { + value: BoltExpression, +} + +node BoltExpressionStatement > BoltStatement { + expression: BoltExpression, +} + +node BoltModule { + modifiers: BoltDeclarationModifiers, + name: BoltQualName, + elements: BoltSourceElement, +} + +node BoltParameter { + index: usize, + bindings: BoltPattern, + typeNode: Option, + defaultValue: Option, +} + +node BoltDeclaration; + +node BoltFunctionDeclaration > BoltDeclaration { + modifiers: BoltDeclarationModifiers, + name: BoltSymbol, + params: Vec, + type: Option, + body: BoltExpression, +} + +node BoltForeignFunctionDeclaration > BoltDeclaration { + modifiers: BoltDeclarationModifiers, + name: BoltSymbol, + params: Vec, + type: Option, + body: FunctionBody, +} + +node BoltVariableDeclaration > BoltDeclaration { + modifiers: BoltDeclarationModifiers, + name: BoltSymbol, + type: Option, + value: Option, +} + +node BoltImportSymbol; + +node BoltPlainImportSymbol > BoltImportSymbol { + name: BoltQualName, +} + +node BoltImportDeclaration > BoltDeclaration { + file: String, + symbols: Vec, +} + +node BoltRecordDeclarationField { + name: BoltIdentifier, + type: BoltTypeNode, +} + +node BoltRecordDeclaration > BoltDeclaration { + name: BoltQualName, + fields: Vec, +} + +// JavaScript AST definitions + +type JSValue = Int | String | Bool | Void; + +node JSToken; + +node JSOperator > JSToken { + text: String, +} + +node JSIdentifier > JSToken { + text: String, +} + +node JSPattern; + +node JSBindPattern { + name: JSIdentifier, +} + +node JSExpression; + +node JSConstantExpression > JSExpression { + value: BoltValue, +} + +enum JSMemberExpressionModifiers { + Computed = 0x1, +} + +node JSMemberExpression > JSExpression { + value: JSExpression, + property: JSExpression, + modifiers: JSMemberExpressionModifiers, +} + +node JSCallExpression > JSExpression { + operator: JSExpression, + operands: Vec, +} + +node JSBinaryExpression > JSExpression { + left: JSExpression, + operator: JSOperator, + right: JSExpression, +} + +node JSUnaryExpression > JSExpression { + operator: JSOperator, + operand: JSExpression +} + +node JSNewExpression > JSExpression { + target: JSExpression, + arguments: Vec, +} + +node JSSequenceExpression > JSExpression { + expressions: Vec, +} + +node JSConditionalExpression > JSExpression { + test: JSExpression, + consequent: JSExpression, + alternate: JSExpression, +} + +node JSReferenceExpression > JSExpression { + name: String, +} + +node JSStatement; + +node JSConditionalStatement > JSStatement { + test: JSExpression, + consequent: Vec, + alternate: Vec, +} + +node JSDeclaration; + +node JSSourceFile { + elements: Vec, +} + +node JSSourceElement > JSDeclaration, JSStatement; +