-
Notifications
You must be signed in to change notification settings - Fork 4
cse-machine-version independent from js-slang #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I would really like to remove the translation layer and just interpret the Python AST directly in the CSE machine. However, I understand that's not feasible with the time left in your project. Could you please open an issue in this repo and say it's a potential FYP/CP3106/CP3108 project for someone else to look at? |
Sure, I can do that. I agree that directly interpreting the Python AST would be a much cleaner approach. |
Fidget-Spinner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good mostly. Just a question from me.
| node: es.ArrowFunctionExpression, | ||
| environment: Environment, | ||
| context: Context, | ||
| dummyReturn: boolean = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is part of the CSE machine spec right? I don't think we need a dummyReturn in Python though. CPython just inserts a return None implicitly in the function.
Nothing to improve here, just me grumbling :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's just mimicking CPython's implicit return of None? I'll add a todo for better implementation options.
src/cse-machine/environment.ts
Outdated
| tail, | ||
| head: {}, | ||
| heap: new Heap(), | ||
| // callExpression 和 thisContext 可选,根据需要传递 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's translate this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry. I will update in next commit
src/cse-machine/stack.ts
Outdated
| // required for first-class continuations, | ||
| // which directly mutate this stack globally. | ||
| public setTo(otherStack: Stack<T>): void { | ||
| this.storage = otherStack.storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this will ever be used in Python. Maybe for generators? Anyways just more grumbling from me :). Nothing to do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you are right. Python do not have CallCC. I removed this part.
| maxExecTime: number | ||
| evaller: null | ((program: string) => Value) | ||
| /* | ||
| the first time evaller is used, it must be used directly like `eval(code)` to inherit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember seeing eval in builtins?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed that part.
Fidget-Spinner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
This PR mainly lays the groundwork for execution in the CSE Machine by setting up the runtime environment and providing utility functions. The core execution logic of the CSE Machine has not yet been implemented.
In the cse-machine folder:
This module provides helper functions for constructing AST (Abstract Syntax Tree) nodes in py-slang. It wraps common operations to simplify the creation, type checking, and structural analysis of AST nodes.
It defines the StatementSequence node, which represents a sequence of statements—commonly used in BlockStatement or Program bodies.
Then it provides AST type guards like isNode, which help ensure type-safe access and logic control.
It also includes AST builder functions (e.g., blockStatement) to simplify AST construction.
Structural analysis functions (e.g., hasDeclarations) check whether a block contains certain kinds of structures.
Custom types are defined to extend ESTree for py-slang’s specific needs. For example, AllowedDeclarations = 'declaration' | 'const', but since Python Chapter 1 only allows single assignment, all current declarations are treated as "const". The "declaration" type is reserved for later chapters that may allow reassignment.
closure.ts
This defines the Closure class, a core component in py-slang used to represent closures.
It normalizes arrow function AST nodes into block statement format (as py-slang, like js-slang, stores functions as arrow functions during execution), and captures the environment and context at the time of function definition—both essential for closures.
context.ts
Defines the Context class, which encapsulates the entire execution state of the CSE machine.
control: the control stack, holding the execution plan (instructions/statements).
stash: the operand stack, used to store intermediate results (similar to a stack-based VM).
errors: collected runtime or syntax errors.
runtime: the core runtime state, including whether it's running, the environment tree, and the active environment.
nativeStorage: internal built-ins like operators, built-in functions, and interpreter settings.
The constructor initializes the control stack, stash, and a global environment (globalEnvironment).
The EnvTree class manages the scope chain as a tree structure. Each Environment is inserted as an EnvTreeNode.
control.ts
Implements the Control class, representing the control stack, the "C" of the CSE machine.
It holds the list of statements/expressions/instructions to execute.
Items are stored as ControlItem, which can be either AST nodes or instructions.
The class defines methods to manipulate the control stack (push, pop, etc.).
environment.ts
Defines the Environment interface, the "E" in CSE machine.
It also provides functions for creating different scopes: createEnvironment, createBlockEnvironment, createProgramEnvironment, etc.
Includes utilities for manipulating the environment.
error.ts
Defines a basic error class that the CSE machine uses to represent issues during execution.
heap.ts
Implements the heap as a utility used by the environment to store values (e.g., arrays or closures).
Every environment is initialized with a heap that tracks objects within that scope. The file defines how to construct and interact with the heap.
instrCreator.ts
Implements a factory for creating intermediate execution instructions (Instr).
In py-slang, expressions/statements are compiled into a sequence of intermediate instructions, and this file defines functions to create those instructions.
stack.ts
Defines a generic stack class Stack, which serves as the base data structure for both the Control and Stash stacks in the CSE machine.
stash.ts
Defines the Value type system and the Stash class for holding runtime values.
Although Value is currently typed as any, interfaces for each expected value type (number, string, bool, etc.) are defined.
types.ts
Defines the intermediate instruction type system, which describes how AST nodes are transformed into executable instructions in the interpreter.
utils.ts
This is a complex utility file that powers a range of interpreter features:
Static AST analysis
Variable/function declaration
Scope management
Runtime checks
Control flow transformation
In the error folder:
runtimeSourceError.ts
Defines the base class RuntimeSourceError for all runtime errors in py-slang.
All custom runtime error classes (e.g., type errors) inherit from this.
error.ts
Defines several common runtime errors (type errors), like:
String + Int concatenation
Missing/extra function arguments
Each error class extends RuntimeSourceError.
In the module folder:
ModuleFunctions
A type definition representing a mapping of module function names to their implementations.
Currently unused as Source Academy modules have not yet been integrated.
In the src folder:
stdlib.ts
Implements Python's built-in str() function and a utility toPythonString() to convert runtime values into Python-style string representations.
toPythonFloat() is used to format numbers like Python does as we discussed before, handling cases like -0.0, inf, nan, scientific notation, etc.
In future PRs (not this one), this file will be extended to include all implemented built-in functions.
types.ts
Defines:
The result structure Result for interpreter execution (e.g., finished, suspended).
The Representation class to control how result values are printed.
The utility type RecursivePartial, which recursively marks properties as optional.
The NativeStorage interface, which holds built-in functions, operator mappings, and other runtime settings.
These are essential for returning well-structured results after the CSE machine finishes execution.