Skip to content

Conversation

@TRK95
Copy link
Contributor

@TRK95 TRK95 commented Aug 10, 2025

This PR adds comprehensive Scheme language support to Source Academy, implementing a complete Scheme Chapter 1 interpreter with direct SCM AST parsing (bypassing JavaScript's ES AST) and full integration with the Source Academy conductor system.

Integration Details:

Feature Flag Configuration:
The Scheme language module is available at:

https://trk95.github.io/scm-slang-pages/dist/index.js
This URL can be used in Source Academy's feature flag system to enable/disable Scheme language support.

Key Features Implemented:

Core Language Features (Scheme Chapter 1):
Variable Definitions: (define x 10) and x → 10
Function Definitions: (define (add x y) (+ x y)) and (add 3 4) → 7
Lambda Expressions: (lambda (x y) (+ x y))
Conditional Statements: (if (> 5 3) "yes" "no") → "yes"
Basic Arithmetic: (+ 3 5), (- 10 3), (* 4 2), (/ 8 2)
Comparisons: (> 5 3), (< 3 5), (= 5 5), (>= 5 5), (<= 3 5)
Boolean Operations: (and #t #f), (or #t #f), (not #f)

Technical Implementation:

  • Direct SCM AST Parsing: Parses Scheme code directly into Scheme-specific AST, avoiding JavaScript ES AST conversion
  • CSE Machine: Complete Control-Stash-Environment machine implementation
  • UMD Module Format: Compatible with browser and Node.js environments
  • Conductor Integration: Full integration with Source Academy's conductor system
  • Environment Persistence: Variables and functions persist across evaluations
  • Error Handling: Comprehensive error reporting with line/column information

Architecture:

Independent Module: Self-contained implementation that can be loaded independently
Feature Flag Ready: Can be enabled/disabled via Source Academy's feature flag system
Extensible Design: Easy to add new Scheme features and chapters

@coveralls
Copy link

coveralls commented Aug 10, 2025

Pull Request Test Coverage Report for Build 17544530225

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 1 of 7 (14.29%) changed or added relevant lines in 1 file are covered.
  • 13 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+2.4%) to 53.236%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/transpiler/types/nodes/scheme-node-types.ts 1 7 14.29%
Files with Coverage Reduction New Missed Lines %
src/transpiler/types/nodes/scheme-node-types.ts 13 58.19%
Totals Coverage Status
Change from base Build 16762143650: 2.4%
Covered Lines: 1380
Relevant Lines: 2395

💛 - Coveralls

TRK95 and others added 17 commits August 11, 2025 03:56
…STORE_ENV instruction to properly restore environment after function calls - Fix function parameter binding in CSE machine - Compound functions now work correctly (functions using other functions) - Linear recursion and iteration working properly
…o handle (list) as function call instead of list literal - Fix car/cdr to work with both lists and pairs - Fix pair? to recognize lists as pairs - Fix list? to recognize empty list () as list - Add length function for lists and pairs - Fix quote syntax to parse 'a 'b 'c as symbols
…ct formatting standards - Fix CI pipeline formatting check
Bumps [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) from 30.0.4 to 30.0.5.
- [Release notes](https://github.com/jestjs/jest/releases)
- [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jestjs/jest/commits/v30.0.5/packages/jest)

---
updated-dependencies:
- dependency-name: jest
  dependency-version: 30.0.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.4.0 to 29.4.1.
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](kulshekhar/ts-jest@v29.4.0...v29.4.1)

---
updated-dependencies:
- dependency-name: ts-jest
  dependency-version: 29.4.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- Add complete CSE machine implementation with SICP Chapter 1 support
- Add Source Academy Conductor integration following py-slang pattern
- Add complex numbers support (exceeds py-slang capabilities)
- Add comprehensive test suite with 100% pass rate
- Add UMD bundle build system for production deployment
- Preserve original transpiler system unchanged
TRK95 added 11 commits September 8, 2025 14:59
…STORE_ENV instruction to properly restore environment after function calls - Fix function parameter binding in CSE machine - Compound functions now work correctly (functions using other functions) - Linear recursion and iteration working properly
…o handle (list) as function call instead of list literal - Fix car/cdr to work with both lists and pairs - Fix pair? to recognize lists as pairs - Fix list? to recognize empty list () as list - Add length function for lists and pairs - Fix quote syntax to parse 'a 'b 'c as symbols
…ct formatting standards - Fix CI pipeline formatting check
Copy link
Member

@s-kybound s-kybound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the limitations of Source chapter 1 in mind, looks good to merge less a few nits:

  • the parsing of ( and [ in the simple parser - both brackets should be counted differently to avoid the valid parsing of examples like ( + 1 2 3 ]
  • it seems like the conductor version loses the scheme numeric tower - only reals and complex numbers are considered now, without integers and rational numbers of (effectively) endless precision
  • other minor nits detailed in the various review comments

"@types/jest": "^29.5.12",
"@types/node": "^22.15.30",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"babel-jest": "^30.0.5",
Copy link
Member

@s-kybound s-kybound Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a downgrade?

nit - please merge the latest set of packages, unless this is necessary

}

/**
* A node that represents a Scheme complex number.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious because in scheme complexes are also considered part of the numeric tower - i intended the "NumericLiteral" class to emcompass all scheme number types - ints, rationals, irrationals and complexes.

was there any specific reason why complex literals are treated differently?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now this is fine. but was there a reason why a test framework like jest wasn't used here?

@@ -0,0 +1,151 @@
// Complex number implementation for Scheme
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm curious as to why complex number logic is separated into its own file. will this affect the scheme numeric tower?

stash: Stash
): void {
if (isInstr(item)) {
console.log("DEBUG: Evaluating instruction:", item.instrType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logging will be captured in the console of the webpage. is this necessary?

"+": (...args: Value[]) => {
if (args.length === 0) return { type: "number", value: 0 };

// Check if all args are numeric (number or complex)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean that integers (big integers) and rational numbers (of type a/b) are not supported in this PR? only javascript numbers (which are reals) and complex numbers?

"list?": (value: Value) => {
return {
type: "boolean",
value: value.type === "list" || value.type === "nil",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean that a value of form pair(0, nil) will not be considered a list?

globalStepCount += 1;
const current = control.shift()!;

// Kiểm tra loại node bằng instanceof
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For team readability, could we switch these comments to English? That way everyone can maintain this code more easily 😅

while (current < code.length) {
const char = code[current];

if (char === "(" || char === "[") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean that ( + 1 2 3 ] will parse as a single s-expr?

return [...this.items];
}
}
//Checking
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if these debug comments will also pop up on the dev console

@martin-henz
Copy link
Member

Thanks for the detailed review @s-kybound. @TRK95 : It seems that we have made tremendous progress with Scheme §1. Please take a close look at Kyriel's comments.

@s-kybound
Copy link
Member

@martin-henz also seems that we are reducing the functionality of scheme at the moment, so i've moved the old repository to the kyriel/old branch so that later devs can restore parts of the scheme functionality back!

@martin-henz
Copy link
Member

martin-henz commented Sep 15, 2025

@martin-henz also seems that we are reducing the functionality of scheme at the moment, so i've moved the old repository to the kyriel/old branch so that later devs can restore parts of the scheme functionality back!

Hmm, that's one way. Or @TRK95 could fix the issues in this PR?

@s-kybound
Copy link
Member

Hmm, that's one way. Or @TRK95 could fix the issues in this PR?

I think the issues listed in the PR should be dealt with here!

  1. The parsing issues of ( and [ should be dealt with
  2. The loss of scheme integers/rationals can be explicitly left as a TODO if there's no time, but it would be nice to reimplement them in this PR if possible

I left the old implementation as reference for future work, for example in restoring first-class continuations, or in reimplementing macros.

@martin-henz
Copy link
Member

Hmm, that's one way. Or @TRK95 could fix the issues in this PR?

I think the issues listed in the PR should be dealt with here!

  1. The parsing issues of ( and [ should be dealt with
  2. The loss of scheme integers/rationals can be explicitly left as a TODO if there's no time, but it would be nice to reimplement them in this PR if possible

I left the old implementation as reference for future work, for example in restoring first-class continuations, or in reimplementing macros.

Noted. Let's make separate issues on macros and first-class continuations so that we know what needs to be done after this PR is merged.

@TRK95
Copy link
Contributor Author

TRK95 commented Sep 16, 2025 via email

@s-kybound
Copy link
Member

@TRK95 don't worry about the new issues, those are unrelated to the scope of the project, and are left here as documentation 😅

are there any updates regarding the changes ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants