Repository navigation
Add C-style types, new language features, standard library tools and CI - #2
Merged
Merged
Conversation
Types
- Optional type annotations: `age: u8 = 30`, `name: string?`, and
`count: i32` (starts at the zero value). Types: i8 i16 i32 i64 u8 u16
u32 u64 byte int f32 f64 float bool char string list map func any, plus
`void` as a return type and `T?` for nullable types.
- Every number carries its type. Arithmetic keeps the type, literals adapt
to the other operand, mixed types widen to a type holding both, and
overflow is an error instead of a silent wrap. f32 keeps 32-bit precision.
- Typed parameters and return types (`func f(a: i32) -> f64`), `const`,
and conversion functions named after each type (`u8(x)`, `f32(x)`, ...).
- Literal type mismatches (`x: u8 = 300`) and wrong return values are
reported before the program runs.
Language
- `char` type and literals ('a', '\u{1F600}'); single quotes now mean a char.
- Strings are Unicode: len, indexing, slicing and loops count characters.
- f-strings with format specs (f"{price:>8.2f}") and format().
- match statements.
- Hex/binary/octal literals, type suffixes (255u8), and bitwise operators
& | ^ ~ << >> with compound assignments.
- Modules via import("file"), with errors reported in the module's file.
Tools
- 124 builtins, including file I/O, JSON, string/list/map helpers, math,
time and system functions.
- `ascend --check file.asc` finds errors without running.
- VS Code syntax highlighting in editors/vscode, checked with the real
TextMate engine.
Also adds 34 tests (110 total), six examples, a CHANGELOG listing the
behavior changes, and updated docs. Builds without warnings on GCC and
Clang; tests and examples are clean under ASan, UBSan and LSan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xWEy3pVr7ofMaomGRbiuo
Types are now written before the name, like in C:
u8 age = 30
string? nickname
const f64 RATE = 0.07
i32 add(i32 a, i32 b = 1) { return a + b }
void log(string message) { print(message) }
Typed parameters are `type name`, and a typed function can put its return
type in front of its name. Untyped code is unchanged (`x := 5`,
`func f(a, b) { }`), anonymous functions can still use `-> type`, and
`func handler = print` declares a variable holding a function. The old
`name: type` form is rejected with a hint showing the C-style spelling.
CI: .github/workflows/build.yml builds and tests on Linux (GCC and Clang),
macOS and Windows (MSVC), runs the tests under ASan and UBSan, and uploads
the built interpreters as artifacts. MSVC now compiles with /utf-8, since
the tests contain UTF-8 text.
Tests, examples, docs, the changelog and the VS Code grammar are updated
for the new syntax (114 tests).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xWEy3pVr7ofMaomGRbiuo
The Windows (MSVC) CI job crashed partway through the unit tests. On Windows the recursion guard assumed an 8 MB stack instead of measuring it, and the parser limited nesting only by a level count, so a smaller stack or larger MSVC stack frames could overflow before either check fired. Add StackLimit, which reads the current thread's actual stack bounds (GetCurrentThreadStackLimits on Windows, the stack rlimit elsewhere) and keeps a safety margin, and use it in both the interpreter and the parser. Runaway recursion and deeply nested code are now reported as errors at any stack size; locally the test suite no longer crashes even with a 256 KB stack. The test runner now prints the available stack and each test's name before running it, so a crash in CI shows which test caused it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014xWEy3pVr7ofMaomGRbiuo
The Windows (MSVC) unit tests still crashed, in interp_recursion_limit_is_an_error_not_a_crash, with the full 8 MB stack available. The stack guard did fire, but each eval/exec level then caught the error to attach a source location and rethrew it. With MSVC, a catch block runs on top of the frames being unwound, so every rethrow starts a new exception dispatch deeper on the stack. Thousands of nested rethrows from deep recursion overflowed it. GCC and Clang unwind differently, so Linux and macOS passed. Record the location in a destructor instead (ErrorSite): creating a RuntimeError sets a flag, and the innermost expression or statement being unwound notes its position and file. The location is applied once at the top level, and `try` clears it. Error messages and locations are unchanged; all error-location tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014xWEy3pVr7ofMaomGRbiuo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds optional C-style types to Ascend, a batch of language upgrades and new builtins, VS Code syntax highlighting, and a GitHub Actions build.
C-style types
i8i16i32i64u8u16u32u64byteintf32f64floatboolcharstringlistmapfuncany,voidfor return types, and nullableT?.u8 x = 300are reported before the program runs.x := 5,func f(a, b) { }). Thename: typeform is rejected with a hint showing the C-style spelling.Language
const,match, f-strings with format specs (f"{price:>8.2f}"), achartype, Unicode-aware strings255u8), bitwise operators& | ^ ~ << >>import("file"); errors inside a module point at that module's fileTools
format, string/list/map helpers, math, time and system functionsascend --check file.ascfinds errors without runningeditors/vscode, checked with VS Code's TextMate engineCI
.github/workflows/build.ymlbuilds and tests on Linux (GCC and Clang), macOS and Windows (MSVC), runs the tests under ASan and UBSan, and uploads the built interpreters as artifacts.Behavior changes
These are listed in
CHANGELOG.md:char, so strings need double quotes.&and|are now bitwise operators; useand/orfor logic.char.s[0] == "a"still works.Windows fix found by CI
The first Windows run crashed in the deep-recursion test. Two commits fix it:
GetCurrentThreadStackLimitson Windows) and also protects the parser.The test runner now prints each test's name before running it, so a future crash shows which test caused it.
Testing
ctest, with no compiler warnings on GCC or Clang.🤖 Generated with Claude Code
https://claude.ai/code/session_014xWEy3pVr7ofMaomGRbiuo