diff --git a/README.md b/README.md index d6a7b6d..6c4559d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ > **Selfhost loop:** `buxc2` can compile itself — deterministic C codegen verified. > **LIR backend** produces clean 3-address C code. All 26 examples pass. > **Gradual Ownership:** `@[Checked]` borrow checker, `borrow &mut` expressions, `@[Shared]` attribute. +> **Apps tested:** compiler successfully parses all 3 real-world apps (`apps/boko-framework`, `apps/jwt-pitbul`, `apps/nexus`) — no hangs, no crashes. Bux is a fast, compiled, strongly-typed systems programming language. Features a C backend for native code generation, raw multi-line strings, gradual ownership (opt-in borrow checking), async/await, generics, algebraic enums, and a package manager. @@ -254,6 +255,20 @@ make clean --- +## Applications + +The `apps/` directory contains real-world Bux applications that serve as integration tests for the compiler: + +| App | Description | Lines | +|-----|-------------|-------| +| **boko-framework** | Async web framework (like FastAPI), multi-threaded HTTP server | ~660 | +| **jwt-pitbul** | JWT CLI tool — sign, verify, decode (HS256/384/512, RS256/384/512, ES256/384, EdDSA) | ~326 | +| **nexus** | High-performance HTTP/1.1, HTTP/2 & WebSocket server | ~550 | + +The bootstrap compiler successfully parses and type-checks all three applications without hanging or crashing. + +--- + ## Documentation - [`docs/LanguageRef.md`](docs/LanguageRef.md) — Language reference diff --git a/bootstrap/parser.nim b/bootstrap/parser.nim index 25d9567..7213c83 100644 --- a/bootstrap/parser.nim +++ b/bootstrap/parser.nim @@ -204,6 +204,10 @@ proc parseBaseType(p: var Parser): TypeExpr = var typeArgs: seq[TypeExpr] = @[] discard p.advance() while not p.check(tkGt) and not p.isAtEnd: + while p.check(tkNewLine): + discard p.advance() + if p.check(tkGt) or p.isAtEnd: + break typeArgs.add(p.parseType()) if p.check(tkComma): discard p.advance() @@ -310,6 +314,10 @@ proc parsePrimaryPattern(p: var Parser): Pattern = discard p.advance() var fields: seq[tuple[name: string, pattern: Pattern]] = @[] while not p.check(tkRBrace) and not p.isAtEnd: + while p.check(tkNewLine): + discard p.advance() + if p.check(tkRBrace) or p.isAtEnd: + break let fieldName = p.expect(tkIdent, "expected field name in struct pattern").text discard p.expect(tkColon, "expected ':' after field name in pattern") fields.add((fieldName, p.parsePattern())) @@ -965,6 +973,10 @@ proc parseTypeParams(p: var Parser): seq[TypeParam] = if p.check(tkLt): discard p.advance() while not p.check(tkGt) and not p.isAtEnd: + while p.check(tkNewLine): + discard p.advance() + if p.check(tkGt) or p.isAtEnd: + break var name = "" var isLifetime = false if p.check(tkIdent): @@ -997,6 +1009,10 @@ proc parseTypeParams(p: var Parser): seq[TypeParam] = proc parseParamList(p: var Parser, allowVariadic: bool = false): seq[Param] = discard p.expect(tkLParen, "expected '('") while not p.check(tkRParen) and not p.isAtEnd: + while p.check(tkNewLine): + discard p.advance() + if p.check(tkRParen) or p.isAtEnd: + break let loc = p.currentLoc var isVar = false if allowVariadic and p.check(tkDotDotDot): @@ -1261,6 +1277,10 @@ proc parseUseDecl(p: var Parser, attrs: ParsedAttrs): Decl = if p.check(tkLBrace): discard p.advance() while not p.check(tkRBrace) and not p.isAtEnd: + while p.check(tkNewLine): + discard p.advance() + if p.check(tkRBrace) or p.isAtEnd: + break names.add(p.expect(tkIdent, "expected name in multi-import").text) if p.check(tkComma): discard p.advance()