diff --git a/AGENTS.md b/AGENTS.md index 7a491d8..5ab45bd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,7 +12,7 @@ You can browse and install extra skills here: blackbox test files (ending in `_test.mbt`) and whitebox test files (ending in `_wbtest.mbt`). -- In the toplevel directory, there is a `moon.mod.json` file listing module +- In the toplevel directory, there is a `moon.mod` file listing module metadata. ## Coding convention diff --git a/CONTRIBUTING-ja.md b/CONTRIBUTING-ja.md index 271caf9..de732bc 100644 --- a/CONTRIBUTING-ja.md +++ b/CONTRIBUTING-ja.md @@ -15,7 +15,7 @@ puruslang/purus ├── bin/ # CLI エントリポイント ├── scripts/ # ビルド・同期スクリプト ├── examples/ # サンプル .purus ファイル -├── moon.mod.json # MoonBit モジュール定義 +├── moon.mod # MoonBit モジュール定義 └── package.json ``` @@ -42,7 +42,7 @@ node scripts/build.js | `moon test` | 全テストの実行 | | `moon check` | 型チェック | | `npm run build` | フルビルド(コンパイル + コピー)| -| `npm run sync` | バージョンを moon.mod.json に同期 | +| `npm run sync` | バージョンを moon.mod に同期 | ## プルリクエストの提出 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f32aed..74aa8f2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ puruslang/purus ├── bin/ # CLI entry point ├── scripts/ # Build & sync scripts ├── examples/ # Sample .purus files -├── moon.mod.json # MoonBit module definition +├── moon.mod # MoonBit module definition └── package.json ``` @@ -42,7 +42,7 @@ node scripts/build.js | `moon test` | Run all tests | | `moon check` | Type check | | `npm run build` | Full build (compile + copy) | -| `npm run sync` | Sync version to moon.mod.json | +| `npm run sync` | Sync version to moon.mod | ## Submitting Pull Requests diff --git a/moon.mod b/moon.mod new file mode 100644 index 0000000..14713a7 --- /dev/null +++ b/moon.mod @@ -0,0 +1,17 @@ +name = "puruslang/purus" + +version = "1.0.0" + +import { + "moonbitlang/x@0.4.40", +} + +readme = "README.md" + +repository = "https://github.com/puruslang/purus" + +license = "Apache-2.0" + +keywords = [ "purus", "compiler", "altjs", "javascript" ] + +description = "A language that compiles to JavaScript — no Shift key required" \ No newline at end of file diff --git a/moon.mod.json b/moon.mod.json deleted file mode 100644 index 6210425..0000000 --- a/moon.mod.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "puruslang/purus", - "version": "1.0.0", - "deps": { - "moonbitlang/x": "0.4.40" - }, - "readme": "README.md", - "repository": "https://github.com/puruslang/purus", - "license": "Apache-2.0", - "keywords": [ - "purus", - "compiler", - "altjs", - "javascript" - ], - "description": "A language that compiles to JavaScript — no Shift key required" -} diff --git a/scripts/sync-version.js b/scripts/sync-version.js index fde4bee..06daf0c 100644 --- a/scripts/sync-version.js +++ b/scripts/sync-version.js @@ -1,5 +1,5 @@ /** - * Sync version from package.json to moon.mod.json + * Sync version from package.json to moon.mod */ const fs = require("fs"); @@ -8,16 +8,26 @@ const path = require("path"); const root = path.join(__dirname, ".."); const version = require(path.join(root, "package.json")).version; -const moonModPath = path.join(root, "moon.mod.json"); -const moonMod = JSON.parse(fs.readFileSync(moonModPath, "utf8")); -const oldVersion = moonMod.version; -moonMod.version = version; -fs.writeFileSync(moonModPath, JSON.stringify(moonMod, null, " ") + "\n", "utf8"); +const moonModPath = path.join(root, "moon.mod"); +const content = fs.readFileSync(moonModPath, "utf8"); + +const versionLine = /^version\s*=\s*"([^"]*)"/m; +const match = content.match(versionLine); +if (!match) { + console.error("Error: no version field found in moon.mod"); + process.exit(1); +} +const oldVersion = match[1]; +fs.writeFileSync( + moonModPath, + content.replace(versionLine, `version = "${version}"`), + "utf8", +); if (oldVersion !== version) { - console.log(`moon.mod.json: ${oldVersion} -> ${version}`); + console.log(`moon.mod: ${oldVersion} -> ${version}`); } else { - console.log(`moon.mod.json: ${version} (no change)`); + console.log(`moon.mod: ${version} (no change)`); } -console.log(`\nAll versions synced to ${version}`); \ No newline at end of file +console.log(`\nAll versions synced to ${version}`); diff --git a/src/cmd/main/moon.pkg b/src/cmd/main/moon.pkg index 7f1392a..e837d0e 100644 --- a/src/cmd/main/moon.pkg +++ b/src/cmd/main/moon.pkg @@ -1,9 +1,9 @@ import { - "puruslang/purus/src/lexer" @lexer, - "puruslang/purus/src/parser" @parser, - "puruslang/purus/src/codegen" @codegen, - "moonbitlang/x/sys" @sys, - "moonbitlang/x/fs" @fs, + "puruslang/purus/src/lexer", + "puruslang/purus/src/parser", + "puruslang/purus/src/codegen", + "moonbitlang/x/sys", + "moonbitlang/x/fs", } options( diff --git a/src/cmd/main/pkg.generated.mbti b/src/cmd/main/pkg.generated.mbti new file mode 100644 index 0000000..2d16360 --- /dev/null +++ b/src/cmd/main/pkg.generated.mbti @@ -0,0 +1,13 @@ +// Generated using `moon info`, DON'T EDIT IT +package "puruslang/purus/src/cmd/main" + +// Values + +// Errors + +// Types and methods + +// Type aliases + +// Traits + diff --git a/src/codegen/moon.pkg b/src/codegen/moon.pkg new file mode 100644 index 0000000..1a89e44 --- /dev/null +++ b/src/codegen/moon.pkg @@ -0,0 +1,7 @@ +import { + "puruslang/purus/src/parser", +} + +import { + "puruslang/purus/src/lexer", +} for "test" \ No newline at end of file diff --git a/src/codegen/moon.pkg.json b/src/codegen/moon.pkg.json deleted file mode 100644 index 1f34fe6..0000000 --- a/src/codegen/moon.pkg.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "import": [ - { "path": "puruslang/purus/src/parser", "alias": "parser" } - ], - "test-import": [ - { "path": "puruslang/purus/src/lexer", "alias": "lexer" } - ] -} diff --git a/src/codegen/pkg.generated.mbti b/src/codegen/pkg.generated.mbti new file mode 100644 index 0000000..fb261f6 --- /dev/null +++ b/src/codegen/pkg.generated.mbti @@ -0,0 +1,26 @@ +// Generated using `moon info`, DON'T EDIT IT +package "puruslang/purus/src/codegen" + +import { + "puruslang/purus/src/parser", +} + +// Values + +// Errors + +// Types and methods +pub(all) struct JsCodegen { + buf : StringBuilder + mut indent_level : Int + mut private_fields : Array[String] + mut declared_vars : Array[String] + cjs : Bool +} +pub fn JsCodegen::generate(Self, Array[@parser.Stmt], header? : String, shebang? : String, strict? : Bool) -> String +pub fn JsCodegen::new(cjs? : Bool) -> Self + +// Type aliases + +// Traits + diff --git a/src/lexer/pkg.generated.mbti b/src/lexer/pkg.generated.mbti new file mode 100644 index 0000000..b90c129 --- /dev/null +++ b/src/lexer/pkg.generated.mbti @@ -0,0 +1,153 @@ +// Generated using `moon info`, DON'T EDIT IT +package "puruslang/purus/src/lexer" + +import { + "moonbitlang/core/debug", +} + +// Values + +// Errors + +// Types and methods +pub(all) struct Lexer { + chars : Array[Char] + mut pos : Int + mut line : Int + mut col : Int + mut tokens : Array[Token] +} +pub fn Lexer::new(String) -> Self +pub fn Lexer::tokenize(Self) -> Array[Token] + +pub(all) struct Token { + kind : TokenKind + line : Int + col : Int +} derive(@debug.Debug) +pub impl Show for Token + +pub(all) enum TokenKind { + Int(Int) + BigInt(String) + Float(Double) + Str(String) + Regex(String, String) + True_ + False_ + Ident(String) + Const_ + Let_ + Var_ + Be + Add + Sub + Mul + Div + Fdiv + Mod + Neg + Pow + Eq + Neq + Lt + Gt + Le + Ge + And + Or + Not + Coal + Band + Bor + Bxor + Bnot + Shl + Shr + Ushr + Fn + Return_ + To + If_ + Elif + Else_ + Unless + Then_ + While_ + Until + Do_ + Yield_ + For_ + In_ + Range_ + Break_ + Continue_ + Match_ + When_ + Switch_ + Case_ + Pipe_ + As + Of + Gives + Typeof_ + Void_ + Instanceof_ + New_ + Delete_ + This_ + Async_ + Await_ + Try_ + Catch_ + Finally_ + Throw_ + Import_ + From_ + Export_ + Default_ + Require_ + Use_ + Mod_ + Public_ + All_ + Type_ + With_ + Class_ + Extends_ + Super_ + Static_ + Private_ + Get_ + Set_ + Null_ + Nil_ + Undefined_ + Nan_ + Infinity_ + List_ + Object_ + LBracket + RBracket + Comma + Semicolon + Dot + DotDot + DotDotDot + Backslash + OptDot + Newline + Indent(Int) + InterpStr(Array[String]) + Blank + Shebang(String) + Comment(String) + BlockComment(String) + Eof +} derive(Eq, @debug.Debug) +pub impl Show for TokenKind + +// Type aliases + +// Traits + diff --git a/src/parser/moon.pkg b/src/parser/moon.pkg index 5e8fc4a..597267c 100644 --- a/src/parser/moon.pkg +++ b/src/parser/moon.pkg @@ -1,3 +1,3 @@ import { - "puruslang/purus/src/lexer" @lexer, + "puruslang/purus/src/lexer", } diff --git a/src/parser/pkg.generated.mbti b/src/parser/pkg.generated.mbti new file mode 100644 index 0000000..c2d37d9 --- /dev/null +++ b/src/parser/pkg.generated.mbti @@ -0,0 +1,204 @@ +// Generated using `moon info`, DON'T EDIT IT +package "puruslang/purus/src/parser" + +import { + "moonbitlang/core/debug", + "puruslang/purus/src/lexer", +} + +// Values + +// Errors + +// Types and methods +pub(all) enum BinOp { + Add + Sub + Mul + Div + Mod + Pow + Eq + Neq + Lt + Gt + Le + Ge + And + Or + Coal + Band + Bor + Bxor + Shl + Shr + Ushr + Fdiv +} derive(@debug.Debug) + +pub(all) struct ClassDecl { + name : String + parent : String? + members : Array[ClassMember] +} + +pub(all) enum ClassMember { + Field(Bool, String, Expr?) + Constructor(Array[String], FnBody) + Method(Bool, Bool, String, Array[String], FnBody) + Getter(String, FnBody) + Setter(String, String, FnBody) +} + +pub(all) enum DeclKind { + Const_ + Let_ + Var_ +} + +pub(all) struct ElIfBranch { + cond : Expr + body : Array[Stmt] +} + +pub(all) enum Expr { + IntLit(Int) + BigIntLit(String) + FloatLit(Double) + StrLit(String) + StrInterp(Array[StrPart]) + RegexLit(String, String) + BoolLit(Bool) + NullLit + UndefinedLit + NanLit + InfinityLit(Bool) + ArrayLit(Array[Expr]) + RangeArray(Expr, Expr, Bool) + Slice(Expr, Expr, Expr, Bool) + ObjectLit(Array[(String, Expr)]) + Ident(String) + DotAccess(Expr, String) + IndexAccess(Expr, Int) + BinOp(BinOp, Expr, Expr) + UnaryNeg(Expr) + UnaryNot(Expr) + UnaryBnot(Expr) + UnaryTypeof(Expr) + UnaryVoid(Expr) + AsCast(Expr, String) + Instanceof(Expr, Expr) + FnExpr(Array[String], Array[Stmt]) + FnExprTo(Array[String], Expr) + Call(Expr, Array[Expr]) + MethodCall(Expr, String, Array[Expr]) + NewExpr(Expr, Array[Expr]) + Pipe(Expr, Expr) + IfExpr(Expr, Expr, Expr) + TryExpr(Array[Stmt], String, Array[Stmt]) + MatchExpr(Expr, Array[MatchArm]) + AwaitExpr(Expr) + DeleteExpr(Expr) + ThisExpr + SuperExpr + OptDotAccess(Expr, String) + OptMethodCall(Expr, String, Array[Expr]) + ComputedAccess(Expr, Expr) + AsyncFnExpr(Array[String], Array[Stmt]) + AsyncFnExprTo(Array[String], Expr) + YieldExpr(Expr?) + PostInc(Expr) + PostDec(Expr) + PreInc(Expr) + PreDec(Expr) +} + +pub(all) enum FnBody { + Block(Array[Stmt]) + ToExpr(Expr) + ToReturnExpr(Expr) +} + +pub(all) struct FnDecl { + name : String? + params : Array[String] + body : FnBody + is_async : Bool + is_generator : Bool +} + +pub(all) enum ImportDecl { + EsImport(String?, Array[String]?, String?, String, Array[(String, Expr)]?) + CjsRequire(String, String) + DynImport(String) + SideEffectImport(String, Array[(String, Expr)]?) +} + +pub(all) struct MatchArm { + pattern : MatchPattern + cond : Expr? + body : MatchBody +} + +pub(all) enum MatchBody { + ExprBody(Expr) + BlockBody(Array[Stmt]) +} + +pub(all) enum MatchPattern { + LitPat(Expr) + BindPat(String) +} + +pub(all) struct Parser { + tokens : Array[@lexer.Token] + mut pos : Int +} +pub fn Parser::new(Array[@lexer.Token]) -> Self +pub fn Parser::parse(Self) -> Array[Stmt] + +pub(all) enum Stmt { + VarDecl(DeclKind, String, Expr) + DestructDecl(DeclKind, Array[String], Expr) + ObjDestructDecl(DeclKind, Array[String], Expr) + DottedVarInit(DeclKind, String, String, Expr) + Assign(Expr, Expr) + CompoundAssign(BinOp, Expr, Expr) + FnDecl(FnDecl) + If(Expr, Array[Stmt], Array[ElIfBranch], Array[Stmt]?) + Unless(Expr, Array[Stmt]) + While(Expr, Array[Stmt]) + Until(Expr, Array[Stmt]) + DoWhile(Expr, Array[Stmt]) + ForIn(String, String?, Expr, Array[Stmt]) + ForRange(String, Expr, Expr, Array[Stmt]) + ForClassic(Stmt, Expr, Stmt, Array[Stmt]) + MatchStmt(Expr, Array[MatchArm]) + PostfixIf(Stmt, Expr) + PostfixUnless(Stmt, Expr) + PostfixFor(Stmt, String, Expr) + TryCatch(Array[Stmt], String?, Array[Stmt], Array[Stmt]?) + Throw(Expr) + Return(Expr?) + Break + Continue + ExprStmt(Expr) + ImportDecl(ImportDecl) + UseStdlib(String, String) + ModDecl(String, Array[Stmt]) + ExportDefault(Stmt) + PublicDecl(Stmt) + TypeDecl(String, Expr) + ClassDecl(ClassDecl) + DeleteStmt(Expr) +} + +pub(all) enum StrPart { + Lit(String) + Interp(Expr) +} + +// Type aliases + +// Traits +