Skip to content

Instantly share code, notes, and snippets.

@fire
Last active December 21, 2025 20:03
Show Gist options
  • Select an option

  • Save fire/029bd0889355ed4323ae682180f03f6a to your computer and use it in GitHub Desktop.

Select an option

Save fire/029bd0889355ed4323ae682180f03f6a to your computer and use it in GitHub Desktop.

GDScript Feature Implementation Status

Based on commit 3e901f6d30e6b50f56686c8cc09bd1319050423a (GDScript-to-RISC-V compiler), this document provides an exhaustive list of GDScript features and their implementation status.

Priority List (Features to Implement)

Features are prioritized by importance, impact, and implementation difficulty. Higher priority features should be implemented first.

⚠️ Important Note: Before adding new language features, the register allocation system needs significant improvements. The current implementation doesn't properly save registers on the stack and isn't register-aware. This foundational issue should be addressed first to avoid technical debt.

🔴 P0 - Critical Priority (Foundation & Infrastructure)

These are foundational issues that should be fixed BEFORE adding new language features:

Feature Status Priority Reason Implementation Notes
Register Allocation: Core Logic ✅ DONE Critical infrastructure - Foundation for all register allocation Simple Greedy Algorithm with Furthest Next Use: The allocator maintains a pool of 18 free physical registers (t0-t6, s1-s11, excluding s0/fp) and maps virtual registers to physical registers using hash maps. When allocating a register for a virtual register, it checks if already allocated (return it), spilled to stack (load it), or new (take from free pool). If the free pool is empty, it picks the virtual register with furthest next use (or unknown) as the spill candidate, stores it to stack, frees its physical register, then allocates that register to the new virtual register. This avoids stack usage when possible. The "furthest next use" heuristic tracks the next instruction position where each virtual register is used, keeping values needed soon in registers and spilling values not needed soon. Note: Stack can store things for a very long time (no limitation on arguments/storage), but registers should be preferred.
Register Allocation: VEVAL Handling ✅ DONE Critical infrastructure - VEVAL is integral for Variant operations VEVAL syscall uses 4 registers (a0, a1, a2, a3). The register allocator handles VEVAL calls by: (1) Calling handle_syscall_clobbering() with clobbered registers (a0-a3) before the syscall, (2) Moving live values from clobbered registers to other available registers, (3) Only spilling to stack if no other registers available. The emit_variant_eval() function now automatically handles register clobbering before making the syscall.
Register Allocation: VCALL Handling ⚠️ NEEDS WORK Critical infrastructure - VCALL is used for all method calls VCALL syscall uses A0-A5 every invocation (6 registers total), takes an array of Variant pointers for arguments (moderate complexity), and if the return variant pointer in a5 is non-null, the return value is written back from the call. Update register allocator to: (1) Track VCALL register clobbering (a0-a5), (2) Move live values to other registers before VCALL, (3) Handle argument array construction efficiently, (4) Only spill to stack if absolutely necessary.
Register Allocation: Remove a0 Stack Spill ✅ DONE Critical infrastructure - Unnecessary overhead No special handling for a0 - the register allocator handles a0 like any other register. The allocator only spills to stack when necessary (no free registers available), not as a special case.
Register Allocation: Tests ✅ DONE Critical infrastructure - Verify improvements work Created tests/tests/test_register_allocation.gd with: (1) Many Variables Test - Function with 15+ local variables (a-o) to test register pressure. (2) Complex Expression Test - Deeply nested expressions requiring many temporary registers. (3) IR verification - Tests verify functionality; IR inspection can verify max_registers <= 25 (leaving room for syscall args: VEVAL uses 4, VCALL uses 6) to ensure stack spilling is avoided.

🟠 P0.5a - Next Steps After Register Allocation

These should be addressed immediately after register allocation is fixed:

Feature Status Priority Reason Implementation Notes
Calling local functions ⚠️ PARTIAL Next priority - "after this we can take a look at calling local functions" Fix function call resolution between functions - may be related to register allocation. User: "after this we can take a look at calling local functions, maybe"
Call operator (.) for Variant methods ⚠️ PARTIAL API access - Enable calling methods on Variants via . operator Support call operator syntax for Variant method calls (e.g., variant.method()). Currently MemberCallExpr exists but may need enhancement for Variant methods specifically. Note: Calling member methods is done using the VCALL system call (fwsgonzo). VCALL uses A0-A5 every invocation (6 registers total), takes an array of Variant pointers for arguments (moderate complexity), and if the return variant pointer in a5 is non-null, the return value is written back from the call. This makes register allocation even more critical. See: https://github.com/libriscv/godot-sandbox/blob/compiler/src/sandbox_syscalls.cpp#L100-L159. User: "possibility of supporting the call operator (.) so that we can call methods on Variants"

🟠 P0.5b - Language Features (To Be Prioritized)

Note: The items listed below are placeholders. Priority and order are to be determined after P0 and P0.5a are complete. (iFire: "the stuff after Calling local functions and Call operator (.) for Variant methods is nonsense" - needs proper prioritization)

Feature Status Priority Reason Implementation Notes
Array literals: [1, 2, 3] ❌ NOT DONE Extremely common - Used in almost every script Parser + AST + CodeGen for array construction
Dictionary literals: {"key": "value"} ❌ NOT DONE Extremely common - Used in almost every script Parser + AST + CodeGen for dictionary construction
For loops (general iterables) ⚠️ PARTIAL Currently only range() works - blocks array/dict iteration Extend gen_for() to handle Array/Dictionary iteration
Const variables: const x = 10 ❌ NOT DONE Common practice - Simple to implement Add const keyword to lexer/parser
Default parameter values ❌ NOT DONE Very common - Used in most function definitions Extend parameter parsing to support defaults
Classes ❌ NOT DONE Foundation for OOP - Enables properties, methods, inheritance Major feature - requires class system design
Properties/Exports ❌ NOT DONE Godot integration - Essential for editor integration Property system + @export annotation parsing
Match statements ❌ NOT DONE Can wait - Defer until register allocation fixed Full parser + AST + CodeGen (fwsgonzo: skeptical about adding features before register alloc fixed)

🟡 P1 - Medium Priority (High Value Features)

These features add significant value and are commonly used:

Feature Status Priority Reason Implementation Notes
Static typing (type hints) ❌ NOT DONE User priority - Performance + safety Type annotation parsing + type checking
Lambdas/Callables ❌ NOT DONE Enables signals - Functional programming Lambda syntax + Callable type support
Signals ❌ NOT DONE User priority - Event-driven programming Signal declaration + emit + connect
In operator: x in array ❌ NOT DONE Common pattern - Membership testing Binary operator + variant membership check
Is operator: x is Type ❌ NOT DONE Type checking - Works with static typing Type checking operator
As operator: x as Type ❌ NOT DONE Type casting - Works with static typing Type casting operator
Recursive functions ⚠️ PARTIAL IR supports it - Just needs testing Verify and test recursive call handling
Assert statement ❌ NOT DONE Robustness - Important for production code Assert statement support (GDScript has assert, but no try-catch)
Function calls between functions ⚠️ PARTIAL Moved to P0 - Critical infrastructure issue Fix function call resolution - may be related to register allocation

🟢 P2 - Low Priority (Nice-to-Have, Can Be Delayed)

These features are useful but can be delayed:

Feature Status Priority Reason Implementation Notes
Async/Await ❌ NOT DONE User said "can be delayed" - Advanced feature Coroutine system + async/await keywords
Bitwise operators ❌ NOT DONE Specialized use - Not commonly needed Add bitwise ops to BinaryExpr
Enums ❌ NOT DONE Type system - Works with static typing Enum declaration + type system integration
Preload ❌ NOT DONE Optimization - Load is already available Compile-time resource loading
Multi-line comments ❌ NOT DONE Convenience - Single-line works Lexer support for ## ... ##
Documentation comments ❌ NOT DONE Documentation - Not critical for functionality Doc comment parsing
Advanced annotations ❌ NOT DONE Editor features - Can use basic @export first Various @export_* annotations
Static variables ❌ NOT DONE Class feature - Depends on classes Static variable storage
Variadic functions ❌ NOT DONE Advanced - Not commonly used Variable argument handling
Named parameters ❌ NOT DONE Convenience - Positional works Parameter name matching

Priority Summary

🔴 P0 (Critical Infrastructure): 5 subtasks - Fix this FIRST before adding features

  • Register Allocation: Core Logic - Make register allocator register-aware. System has 31 registers available. Should move to OTHER registers first, ONLY spill to stack if there is literally no other choice.
  • Register Allocation: VEVAL Handling - VEVAL syscall uses 4 registers (a0-a3), a0 is return value. Handle register clobbering properly.
  • Register Allocation: VCALL Handling - VCALL syscall uses A0-A5 every invocation (6 registers total), takes an array of Variant pointers for arguments. Handle register clobbering and argument array construction efficiently.
  • Register Allocation: Remove a0 Stack Spill - Remove unnecessary special case where a0 is always saved to stack. Use other registers instead.
  • Register Allocation: Tests - Create test file with many variables test, complex expression test, and IR verification to ensure stack spilling is avoided.

🟠 P0.5a (Next After Register Allocation): 2 features - Address immediately after register alloc is fixed

  • Calling local functions - Fix function call resolution between functions (user: "after this we can take a look at calling local functions, maybe")
  • Call operator (.) for Variant methods - Enable calling methods on Variants via . operator (user: "possibility of supporting the call operator (.) so that we can call methods on Variants")

🟠 P0.5b (Language Features - To Be Prioritized): 6 features - Priority and order TBD after P0 and P0.5a are complete (iFire: "the stuff after Calling local functions and Call operator (.) for Variant methods is nonsense" - needs proper prioritization)

  • Array/Dictionary literals (most common syntax)
  • For loops with iterables (unlocks iteration)
  • Const variables (simple, high value)
  • Default parameters (very common)
  • Classes (foundation for OOP)
  • Properties/Exports (Godot integration)

🟡 P1 (Medium Priority): 8 features - Add significant value

  • Static typing, Lambdas, Signals, Operators (in, is, as), Assert, Recursive functions

🟢 P2 (Low Priority): 11+ features - Can be delayed

  • Match statements (defer until register alloc fixed - fwsgonzo skeptical)
  • Async/Await (user said can delay), Bitwise ops, Enums, Preload, Comments, Advanced annotations

Key Insight from Team Discussion: Register allocation is the critical blocker. Adding features before fixing this creates technical debt. Match statements can wait.

Exhaustive Feature List (Sorted by Cold Start Order)

Features are organized in the order you would learn/implement them when starting from scratch.

1. Comments & Documentation

Feature Status Notes
Single-line comments: # comment ✅ DONE Handled by lexer
Multi-line comments: ## comment ## ❌ NOT DONE 🟢 P2 - No multi-line comments
Documentation comments ❌ NOT DONE 🟢 P2 - No doc comment support

2. Data Types & Literals

Feature Status Notes
Integer literals (42, -100) ✅ DONE LiteralExpr::Type::INTEGER
Float literals (3.14, 2.5) ✅ DONE LiteralExpr::Type::FLOAT
String literals ("hello", 'world') ✅ DONE LiteralExpr::Type::STRING
Boolean literals (true, false) ✅ DONE LiteralExpr::Type::BOOL
Null literal (null) ✅ DONE LiteralExpr::Type::NULL_VAL
Array literals ([1, 2, 3]) ❌ NOT DONE 🟠 P0.5 - Listed as "Not Yet Implemented"
Dictionary literals ({"key": "value"}) ❌ NOT DONE 🟠 P0.5 - Listed as "Not Yet Implemented"
Vector2 literals ❌ NOT DONE No vector literal syntax (but available via Variant)
Vector3 literals ❌ NOT DONE No vector literal syntax (but available via Variant)
Color literals ❌ NOT DONE No color literal syntax (but available via Variant)
Transform literals ❌ NOT DONE No transform literal syntax (but available via Variant)
Typed arrays (Array[int]) ❌ NOT DONE No static typing support
Typed dictionaries (Dictionary<String, int>) ❌ NOT DONE No static typing support

3. Variables & Scope

Feature Status Notes
Variable declaration: var x = 10 ✅ DONE VarDeclStmt
Variable assignment: x = 20 ✅ DONE AssignStmt
Uninitialized variables: var x ✅ DONE Initialized to null/0
Local scope ✅ DONE Scope management in CodeGenerator
Static variables: static var x ❌ NOT DONE No static keyword
Const variables: const x = 10 ❌ NOT DONE 🟠 P0.5 - No const keyword
Type hints: var x: int = 10 ❌ NOT DONE 🟡 P1 - No static typing

4. Operators

Feature Status Notes
Arithmetic: +, -, *, /, % ✅ DONE BinaryExpr::Op::ADD/SUB/MUL/DIV/MOD
Comparison: ==, !=, <, <=, >, >= ✅ DONE BinaryExpr::Op::EQ/NEQ/LT/LTE/GT/GTE
Logical: and, or, not ✅ DONE BinaryExpr::Op::AND/OR, UnaryExpr::Op::NOT
Unary: -x, not y ✅ DONE UnaryExpr::Op::NEG/NOT
Assignment: = ✅ DONE AssignStmt
Compound assignment: +=, -=, *=, /=, %= ✅ DONE Tested in test_gdscript_compiler.gd
Bitwise: &, |, ^, ~, <<, >> ❌ NOT DONE 🟢 P2 - No bitwise operators
In operator: x in array ❌ NOT DONE 🟡 P1 - No in operator for membership
Is operator: x is Type ❌ NOT DONE 🟡 P1 - No type checking operator
As operator: x as Type ❌ NOT DONE 🟡 P1 - No type casting operator

5. Basic Control Flow

Feature Status Notes
If statement: if condition: ✅ DONE IfStmt
Elif statement: elif condition: ✅ DONE Handled in parse_if_stmt()
Else statement: else: ✅ DONE IfStmt::else_branch
While loop: while condition: ✅ DONE WhileStmt
Break statement: break ✅ DONE BreakStmt
Continue statement: continue ✅ DONE ContinueStmt
Pass statement: pass ✅ DONE PassStmt

6. Functions

Feature Status Notes
Function declaration: func name(): ✅ DONE FunctionDecl
Function parameters: func add(a, b): ✅ DONE Parameter struct
Function calls: add(1, 2) ✅ DONE CallExpr
Return statement: return value ✅ DONE ReturnStmt
Return without value: return ✅ DONE ReturnStmt with null value
Default parameter values ❌ NOT DONE 🟠 P0.5 - No default arguments
Named parameters: func(x=1, y=2) ❌ NOT DONE 🟢 P2 - No named arguments
Variadic functions: func sum(...args) ❌ NOT DONE 🟢 P2 - No variadic support
Return type hints: func add() -> int: ❌ NOT DONE 🟡 P1 - No static typing
Parameter type hints: func add(a: int, b: int): ❌ NOT DONE 🟡 P1 - No static typing
Static functions: static func name(): ❌ NOT DONE 🟢 P2 - No static keyword
Virtual functions ❌ NOT DONE No class system
Overriding functions ❌ NOT DONE No inheritance
Recursive functions ⚠️ PARTIAL 🟡 P1 - IR supports it, but not fully tested

14. Classes & Object-Oriented Programming

Feature Status Notes
Class declaration: class Name: ❌ NOT DONE Listed as "Not Yet Implemented"
Class inheritance: extends BaseClass ❌ NOT DONE No class system
Class instantiation: var obj = Class.new() ❌ NOT DONE No class system
Instance variables ❌ NOT DONE No class system
Instance methods ❌ NOT DONE No class system
Class variables: static var x ❌ NOT DONE No class system
Class methods: static func name(): ❌ NOT DONE No class system
Inner classes ❌ NOT DONE No class system
Abstract classes ❌ NOT DONE No class system
Virtual methods ❌ NOT DONE No class system
Method overriding ❌ NOT DONE No inheritance
Super keyword: super.method() ❌ NOT DONE No inheritance
Self keyword: self.property ❌ NOT DONE No class system
Constructor: _init() ❌ NOT DONE No class system
Destructor: _exit_tree() ❌ NOT DONE No class system

15. Properties & Exports

Feature Status Notes
Property declaration: var x: int ❌ NOT DONE No class system
Property getter: var x: get = get_x ❌ NOT DONE Listed as "Not Yet Implemented"
Property setter: var x: set = set_x ❌ NOT DONE Listed as "Not Yet Implemented"
Property getter/setter: var x: get = get_x, set = set_x ❌ NOT DONE No property support
Export annotation: @export var x: int ❌ NOT DONE Listed as "Not Yet Implemented"
Export group: @export_group("Group") ❌ NOT DONE No annotation support
Export subgroup: @export_subgroup("Sub") ❌ NOT DONE No annotation support
Export range: @export_range(0, 100) var x ❌ NOT DONE No annotation support
Export enum: @export_enum("A", "B") var x ❌ NOT DONE No annotation support
Export file: @export_file var path ❌ NOT DONE No annotation support
Export dir: @export_dir var path ❌ NOT DONE No annotation support
Export multiline: @export_multiline var text ❌ NOT DONE No annotation support
Export placeholder: @export_placeholder var text ❌ NOT DONE No annotation support
Export color no alpha: @export_color_no_alpha var color ❌ NOT DONE No annotation support
Export flags: @export_flags var flags ❌ NOT DONE No annotation support
Export flags 2D: @export_flags_2d_* ❌ NOT DONE No annotation support
Export flags 3D: @export_flags_3d_* ❌ NOT DONE No annotation support
Onready annotation: @onready var node ❌ NOT DONE Listed as "Not Yet Implemented"
Tool annotation: @tool ❌ NOT DONE No annotation support
Export category: @export_category("Cat") ❌ NOT DONE No annotation support

16. Signals & Events

Feature Status Notes
Signal declaration: signal my_signal ❌ NOT DONE Listed as "Not Yet Implemented"
Signal with parameters: signal hit(damage: int) ❌ NOT DONE No signal support
Signal emission: emit_signal("name", args) ❌ NOT DONE No signal support
Signal connection: obj.connect("signal", callback) ❌ NOT DONE No signal support
Signal disconnection: obj.disconnect("signal", callback) ❌ NOT DONE No signal support
Signal is_connected check ❌ NOT DONE No signal support
Await signal: await signal_name ❌ NOT DONE No async/await support

17. Lambdas & Callables

Feature Status Notes
Lambda functions: func(x): return x * 2 ❌ NOT DONE Listed as "Not Yet Implemented"
Callable creation: Callable(obj, "method") ❌ NOT DONE No callable syntax
Callable from function: Callable(self, "func_name") ❌ NOT DONE No callable syntax
Callable binding: callable.bind(args) ❌ NOT DONE No callable support
First-class functions ❌ NOT DONE Functions can't be assigned to variables

18. Async/Await & Coroutines

Feature Status Notes
Async functions: func async_func(): ❌ NOT DONE Listed as "Not Yet Implemented"
Await keyword: await some_operation() ❌ NOT DONE Listed as "Not Yet Implemented"
Coroutines ❌ NOT DONE No coroutine support
Yield (deprecated) ❌ NOT DONE No yield support

7. For Loops

Feature Status Notes
For loop: for i in range(n): ✅ DONE ForStmt - Working (tested)
For loop (general iterables) ⚠️ PARTIAL 🟠 P0.5 - Only range() supported, not general iterables
Array iteration: for item in array: ⚠️ PARTIAL 🟠 P0.5 - Only range() works, not arrays
Dictionary iteration: for key in dict: ❌ NOT DONE 🟠 P0.5 - No dictionary iteration

8. Collections & Data Structures

Feature Status Notes
Array literals: [1, 2, 3] ❌ NOT DONE Listed as "Not Yet Implemented"
Dictionary literals: {"key": "value"} ❌ NOT DONE Listed as "Not Yet Implemented"
Array indexing: arr[0] ✅ DONE IndexExpr - compiles to variant ops
Dictionary access: dict["key"] ✅ DONE Via indexing - IndexExpr
Array methods (push_back, pop_back, etc.) ✅ DONE All Array methods available via Variant.callp()
Dictionary methods (keys, values, etc.) ✅ DONE All Dictionary methods available via Variant.callp()
Array iteration: for item in array: ⚠️ PARTIAL Only range() works, not arrays
Dictionary iteration: for key in dict: ❌ NOT DONE No dictionary iteration
Packed arrays (PackedByteArray, etc.) ✅ DONE Available via Variant - Can create and use via method calls
Typed arrays ❌ NOT DONE No static typing syntax

10. Member Access & Method Calls

Feature Status Notes
Member access: obj.property ✅ DONE MemberCallExpr with empty args
Method calls: obj.method(args) ✅ DONE MemberCallExpr - compiles to VCALL syscall (fwsgonzo)
Chained calls: obj.get_node().method() ✅ DONE Expression nesting supported
Null-safe access: obj?.property ❌ NOT DONE No null-safe operator
Any Variant method ✅ DONE All Variant types support method calls - Array, Dictionary, String, Object, etc.

11. Built-in Types & Utilities

Feature Status Notes
Vector2 type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Vector3 type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Vector2i type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Vector3i type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Color type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Transform2D type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Transform3D type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Rect2 type ✅ DONE Available via Variant - Can create and use via Variant.callp()
AABB type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Plane type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Quaternion type ✅ DONE Available via Variant - Can create and use via Variant.callp()
Basis type ✅ DONE Available via Variant - Can create and use via Variant.callp()
RID type ✅ DONE Available via Variant - Can create and use via Variant.callp()
NodePath type ✅ DONE Available via Variant - Can create and use via Variant.callp()
StringName type ✅ DONE Available via Variant - Can create and use via Variant.callp()
All Variant types ✅ DONE Full Variant type system accessible - All 40+ Variant types supported

12. Match Statements (Advanced Control Flow)

Feature Status Notes
Match statement: match value: ❌ NOT DONE 🟢 P2 - Listed as "Not Yet Implemented" (defer until register alloc fixed)
Match patterns (literals, ranges, etc.) ❌ NOT DONE 🟢 P2 - No match support (defer until register alloc fixed)
Match binding: match x: 1: var y = x ❌ NOT DONE 🟢 P2 - No match support (defer until register alloc fixed)
Switch-like behavior ❌ NOT DONE 🟢 P2 - No match support (defer until register alloc fixed)

13. Static Typing

Feature Status Notes
Type hints: var x: int ❌ NOT DONE Listed as "Not Yet Implemented"
Return type hints: func f() -> String: ❌ NOT DONE Listed as "Not Yet Implemented"
Parameter type hints: func f(x: int): ❌ NOT DONE Listed as "Not Yet Implemented"
Type inference ❌ NOT DONE No type system
Type checking: is operator ❌ NOT DONE No type checking
Type casting: as operator ❌ NOT DONE No type casting
Typed arrays: Array[int] ❌ NOT DONE No typed collections
Typed dictionaries: Dictionary<String, int> ❌ NOT DONE No typed collections
Generic types ❌ NOT DONE No generics

14. Classes & Object-Oriented Programming

Feature Status Notes
Class declaration: class Name: ❌ NOT DONE Listed as "Not Yet Implemented"
Class inheritance: extends BaseClass ❌ NOT DONE No class system
Class instantiation: var obj = Class.new() ❌ NOT DONE No class system
Instance variables ❌ NOT DONE No class system
Instance methods ❌ NOT DONE No class system
Class variables: static var x ❌ NOT DONE No class system
Class methods: static func name(): ❌ NOT DONE No class system
Inner classes ❌ NOT DONE No class system
Abstract classes ❌ NOT DONE No class system
Virtual methods ❌ NOT DONE No class system
Method overriding ❌ NOT DONE No inheritance
Super keyword: super.method() ❌ NOT DONE No inheritance
Self keyword: self.property ❌ NOT DONE No class system
Constructor: _init() ❌ NOT DONE No class system
Destructor: _exit_tree() ❌ NOT DONE No class system

15. Properties & Exports

Feature Status Notes
Property declaration: var x: int ❌ NOT DONE No class system
Property getter: var x: get = get_x ❌ NOT DONE Listed as "Not Yet Implemented"
Property setter: var x: set = set_x ❌ NOT DONE Listed as "Not Yet Implemented"
Property getter/setter: var x: get = get_x, set = set_x ❌ NOT DONE No property support
Export annotation: @export var x: int ❌ NOT DONE Listed as "Not Yet Implemented"
Export group: @export_group("Group") ❌ NOT DONE No annotation support
Export subgroup: @export_subgroup("Sub") ❌ NOT DONE No annotation support
Export range: @export_range(0, 100) var x ❌ NOT DONE No annotation support
Export enum: @export_enum("A", "B") var x ❌ NOT DONE No annotation support
Export file: @export_file var path ❌ NOT DONE No annotation support
Export dir: @export_dir var path ❌ NOT DONE No annotation support
Export multiline: @export_multiline var text ❌ NOT DONE No annotation support
Export placeholder: @export_placeholder var text ❌ NOT DONE No annotation support
Export color no alpha: @export_color_no_alpha var color ❌ NOT DONE No annotation support
Export flags: @export_flags var flags ❌ NOT DONE No annotation support
Export flags 2D: @export_flags_2d_* ❌ NOT DONE No annotation support
Export flags 3D: @export_flags_3d_* ❌ NOT DONE No annotation support
Onready annotation: @onready var node ❌ NOT DONE Listed as "Not Yet Implemented"
Tool annotation: @tool ❌ NOT DONE No annotation support
Export category: @export_category("Cat") ❌ NOT DONE No annotation support

16. Signals & Events

Feature Status Notes
Signal declaration: signal my_signal ❌ NOT DONE Listed as "Not Yet Implemented"
Signal with parameters: signal hit(damage: int) ❌ NOT DONE No signal support
Signal emission: emit_signal("name", args) ❌ NOT DONE No signal support
Signal connection: obj.connect("signal", callback) ❌ NOT DONE No signal support
Signal disconnection: obj.disconnect("signal", callback) ❌ NOT DONE No signal support
Signal is_connected check ❌ NOT DONE No signal support
Await signal: await signal_name ❌ NOT DONE No async/await support

17. Lambdas & Callables

Feature Status Notes
Lambda functions: func(x): return x * 2 ❌ NOT DONE Listed as "Not Yet Implemented"
Callable creation: Callable(obj, "method") ❌ NOT DONE No callable syntax
Callable from function: Callable(self, "func_name") ❌ NOT DONE No callable syntax
Callable binding: callable.bind(args) ❌ NOT DONE No callable support
First-class functions ❌ NOT DONE Functions can't be assigned to variables

18. Async/Await & Coroutines

Feature Status Notes
Async functions: func async_func(): ❌ NOT DONE Listed as "Not Yet Implemented"
Await keyword: await some_operation() ❌ NOT DONE Listed as "Not Yet Implemented"
Coroutines ❌ NOT DONE No coroutine support
Yield (deprecated) ❌ NOT DONE No yield support

19. Error Handling

Feature Status Notes
Assert statement: assert condition ❌ NOT DONE 🟡 P1 - No assert support
Error handling ❌ NOT DONE No error handling
Push error: push_error("msg") ❌ NOT DONE No error functions
Push warning: push_warning("msg") ❌ NOT DONE No warning functions

20. Preprocessor & Annotations

Feature Status Notes
@export annotation ❌ NOT DONE Listed as "Not Yet Implemented"
@onready annotation ❌ NOT DONE Listed as "Not Yet Implemented"
@tool annotation ❌ NOT DONE No annotation support
@export_* annotations ❌ NOT DONE No annotation support
Preprocessor directives ❌ NOT DONE No preprocessor

21. Godot API Integration

Feature Status Notes
get_node() calls ✅ DONE Via ECALL_GET_NODE syscall
print() function ✅ DONE Via ECALL_PRINT syscall
Node methods ✅ DONE All Node methods accessible via Variant.callp()
Scene tree access ✅ DONE Available - Can access scene tree via Object methods
Resource loading ✅ DONE Via ECALL_LOAD syscall
Input handling ✅ DONE Available - Input class methods accessible via Variant
Rendering API ✅ DONE Available - All rendering classes accessible via Variant
Physics API ✅ DONE Available - All physics classes accessible via Variant
Audio API ✅ DONE Available - All audio classes accessible via Variant
Networking API ✅ DONE Available - All networking classes accessible via Variant
File system API ✅ DONE Available - FileAccess, DirAccess accessible via Variant
OS API ✅ DONE Available - OS class methods accessible via Variant
Any Godot class method ✅ DONE Full Godot API accessible - Any method on any class via Variant.callp()
ClassDB instantiation ✅ DONE Via ECALL_NODE_CREATE with CREATE_CLASSDB
Object property get/set ✅ DONE Via ECALL_OBJ_PROPERTY_GET/SET
Object method calls ✅ DONE Via ECALL_OBJ_CALLP

22. Advanced Features

Feature Status Notes
Enums: enum Name { VALUE } ❌ NOT DONE 🟢 P2 - No enum support
Constants: const NAME = value ❌ NOT DONE 🔴 P0 - No const keyword (note: different from const variables)
Preload: preload("res://path") ❌ NOT DONE No preload support
Load: load("res://path") ✅ DONE Via ECALL_LOAD syscall
Resource paths: res://, user:// ❌ NOT DONE No path constants
Groups: add_to_group(), is_in_group() ❌ NOT DONE No group support
Autoload singletons ❌ NOT DONE No autoload support
Scene tree notifications ❌ NOT DONE No lifecycle hooks
Process/Physics process ❌ NOT DONE No built-in callbacks
Input callbacks ❌ NOT DONE No input handling
Coroutines ❌ NOT DONE No coroutine support
Threading ❌ NOT DONE No threading support
Reflection: get_method_list(), etc. ❌ NOT DONE No reflection

Summary by Category

Based on commit 3e901f6d30e6b50f56686c8cc09bd1319050423a:

✅ Fully Implemented Categories

  • Basic Data Types: Integers, floats, strings, booleans, null
  • Basic Operators: Arithmetic, comparison, logical, unary, assignment, compound assignment
  • Variables: Declaration, assignment, local scope
  • Basic Control Flow: if/elif/else, while, break, continue, pass
  • Functions: Declaration, parameters, calls, return
  • For Loops: Working with range() (tested and confirmed)
  • Member Access: Property access and method calls (via syscalls)
  • Array Indexing: arr[index] syntax
  • Comments: Single-line comments

⚠️ Partially Implemented Categories

  • For Loops: Only range() supported, not general iterables
  • Collections: Indexing works, but no literals (methods fully accessible)
  • String Operations: Basic operations work, but no multiline/interpolation syntax

❌ Not Implemented Categories

  • Classes & OOP: No class system at all
  • Properties & Exports: No property system or annotations
  • Signals & Events: No signal support
  • Lambdas & Callables: No lambda or callable syntax
  • Async/Await: No coroutine or async support
  • Static Typing: No type hints or type system
  • Match Statements: No pattern matching
  • Collection Literals: No array/dictionary literal syntax (but methods work)
  • Error Handling: No assert (GDScript has assert but compiler doesn't support it yet)
  • Annotations: No @export, @onready, @tool, etc.
  • Advanced Features: No enums, const, preload, groups, etc.

Priority List Status (From User's List)

The following features were mentioned in the priority list:

1. For Loops ✅ (DONE - Confirmed Working)

  • Status: DONE (Confirmed working in tests)
  • Evidence from commit:
    • ForStmt AST node exists (src/gdscript/compiler/ast.h:158)
    • Parser supports for variable in iterable: (src/gdscript/compiler/parser.cpp:169-179)
    • Code generator implements gen_for() (src/gdscript/compiler/codegen.cpp:202)
    • Multiple test cases exist (src/gdscript/compiler/tests/test_integration.cpp:513-835)
    • Working test example (tests/tests/test_gdscript_compiler.gd:10-12):
      func sum1(n):
          var total = 0
          for i in range(n):
              total += i
          return total
      This test passes and returns correct results (e.g., sum1(10) = 45)
    • Currently supports range() calls only (not general iterables)
  • Implementation: For loops are desugared into while loops with range iteration
  • Note: Despite being listed under "Not Yet Supported" in the priority list, for loops ARE actually implemented and working

2. Match Statements

  • Status: NOT DONE (Confirmed not implemented)
  • Evidence from commit:
    • Listed in "Not Yet Implemented" section (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:183)
    • No MatchStmt AST node in ast.h
    • No parser support for match keyword (no parse_match_stmt() in parser)
    • No codegen support (no gen_match() function)
    • No tests
    • No token type for MATCH keyword
  • Note: Despite being mentioned as "was mentioned done", match statements are NOT implemented

3. Properties/Exports

  • Status: NOT DONE (in GDScript compiler)
  • Evidence from commit:
    • Listed in "Not Yet Implemented" section (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:188-189)
    • No property getters/setters support
    • No @export annotation support
    • No @onready annotation support
  • Note: Properties work for C++/Rust/Zig programs via add_property(), but NOT for GDScript compilation

4. Lambdas/Signals

  • Status: NOT DONE (in GDScript compiler)
  • Evidence from commit:
    • Listed in "Not Yet Implemented" section (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:185-187)
    • No lambda function support
    • No signal support
    • No callable syntax in GDScript
  • Note: Callables/Signals work for C++/Rust/Zig programs, but NOT for GDScript compilation

❌ NOT DONE (Not Implemented in GDScript Compiler)

5. Classes

  • Status: NOT DONE
  • Evidence from commit:
    • Listed in "Not Yet Implemented" section (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:180)
    • No class definition syntax
    • No object instantiation
    • No method-to-property association
    • The (object, array, dictionary) int to slot system mentioned is not implemented
  • What exists: Only standalone functions, no class system

6. Most of the Godot API ⚠️

  • Status: PARTIALLY DONE (via syscalls, not direct API)
  • Evidence from commit:
    • Method calls compile to syscalls (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:174)
    • Member access obj.method(args) works via syscall interface
    • Array indexing arr[0] compiles to variant operations
  • What's missing:
    • No direct Godot class access in GDScript
    • Must use syscall interface for all Godot API access
    • Limited compared to full GDScript API

7. Advanced Data Structures

  • Status: NOT DONE
  • Evidence from commit:
    • Array/Dictionary literals [], {} listed as "Not Yet Implemented" (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:184)
    • No custom data structure support
    • Only basic types (int, float, string, bool, null) supported

8. Await/Async

  • Status: NOT DONE
  • Evidence from commit:
    • Listed in "Not Yet Implemented" section (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:186)
    • No async/await syntax
    • No coroutine support
    • No async function compilation

9. Static Typing

  • Status: NOT DONE
  • Evidence from commit:
    • Listed in "Not Yet Implemented" section (src/gdscript/compiler/GDSCRIPT_COMPILER_IMPLEMENTATION.md:181)
    • No type annotations (: int, -> String)
    • No static type checking
    • No register machine optimization for type hints
    • All variables are dynamically typed (Variant)

Summary Table (Based on commit 3e901f6d30e6b50f56686c8cc09bd1319050423a)

Feature Status Notes
For loops ✅ DONE Working - Tested and confirmed in test_gdscript_compiler.gd
Match statements ❌ NOT DONE Not implemented (despite being "mentioned done")
Properties ❌ NOT DONE No property getters/setters in GDScript
Exports ❌ NOT DONE No @export annotation support
Classes ❌ NOT DONE No class definition syntax
Lambdas ❌ NOT DONE No lambda function support
Signals ❌ NOT DONE No signal support in GDScript compiler
Godot API ⚠️ PARTIAL Via syscalls only, not direct API
Advanced data structures ❌ NOT DONE No Array/Dictionary literals
Await/Async ❌ NOT DONE Not implemented
Static typing ❌ NOT DONE No type annotations (: int, -> String)

Key Findings from Commit 3e901f6d30e6b50f56686c8cc09bd1319050423a

  1. For loops ARE implemented and WORKING

    • Full parser, AST, codegen, and test support
    • Confirmed working in tests/tests/test_gdscript_compiler.gd with for i in range(n):
    • Currently only supports range() calls, not general iterables
    • Despite being listed under "Not Yet Supported" in the priority list, they ARE actually done
  2. Match statements are NOT implemented

    • Despite being mentioned as "was mentioned done", they are NOT implemented
    • No AST node, parser support, codegen, or tests
    • Explicitly listed as "Not Yet Implemented" in documentation
  3. Most features are NOT implemented - The GDScript compiler is a basic implementation with:

    • ✅ Functions, variables, if/while/for loops
    • ✅ Basic expressions and operators
    • ❌ Classes, match, properties, exports, lambdas, async, static typing
  4. This is a GDScript-to-RISC-V compiler - It compiles GDScript source to RISC-V ELF binaries, not a runtime feature of the sandbox itself.

  5. The compiler is WIP - The commit message says "WIP: GDScript-to-RISC-V", indicating it's work in progress.

Implementation Statistics

Total Features Listed: ~150+ GDScript features

Implemented: ~60+ features (40%)

  • Basic data types (5)
  • Basic operators (11)
  • Basic control flow (8)
  • Functions (5)
  • For loops (1) - Working and tested
  • Full Variant API (~30+ features) - All Variant types and methods accessible via Variant.callp()
  • Full Godot API (~10+ features) - All Godot classes accessible via method calls

Partially Implemented: ~5 features (3%)

  • For loops (general iterables)
  • Collections (indexing works, but no literals)
  • String operations (methods work, but no multiline/interpolation syntax)

Not Implemented: ~85+ features (57%)

  • All class/OOP features
  • All property/export features
  • All signal/event features
  • All async/await features
  • All static typing features
  • Collection literals (syntax only - methods work)
  • Advanced language features

Discrepancy Note

There's a discrepancy between the priority list (which says "For loops (was mentioned done)" and "Match statements (was mentioned done)" under "Not Yet Supported") and the actual implementation:

  • For loops: Listed as "Not Yet Supported" but ARE actually implemented and working (confirmed by tests in test_gdscript_compiler.gd)
  • Match statements: Listed as "Not Yet Supported" and ARE NOT implemented (no code exists)

Important Note: Variant API Surface Area

The compiler provides access to the FULL Godot API via Variant method calls, even if direct syntax isn't supported:

  • All Variant types (40+ types) are accessible: Vector2, Vector3, Color, Transform, Array, Dictionary, String, etc.
  • All Variant methods are callable via Variant.callp("method_name", args)
  • All Godot class methods are accessible via obj.method(args) which compiles to ECALL_VCALL
  • All built-in types can be created and manipulated via method calls
  • Full API surface area - Any method on any Godot class is accessible

What's missing is syntax sugar, not functionality:

  • ❌ Can't write [1, 2, 3] but can call Array().push_back(1).push_back(2).push_back(3)
  • ❌ Can't write {"key": "value"} but can call Dictionary().set("key", "value")
  • ❌ Can't write Vector2(1, 2) but can create via method calls
  • ❌ Can't use type hints but can use all types via Variant

Conclusion

The GDScript-to-RISC-V compiler in commit 3e901f6d30e6b50f56686c8cc09bd1319050423a implements:

  • ✅ Function-based programming (no classes)
  • ✅ Basic control flow (if/while/for)
  • ✅ Basic expressions and operators
  • ✅ Variable management
  • Full Variant API access via method calls
  • Full Godot API access via method calls

The compiler provides access to ~40% of GDScript features directly, but ~80%+ of Godot API functionality is accessible via Variant method calls. The main limitations are:

  • Language syntax features (classes, properties, signals, async, etc.)
  • Literal syntax (array/dictionary literals)
  • Type system (static typing, type hints)

The foundation is solid, and the Variant-based API access means most Godot functionality is available, just not with the same syntax as full GDScript.

Recent Work & Testing Infrastructure

Testing & Build System Improvements

Date: December 2024

Compiler Unit Tests

  • CMake-based test suite - All compiler unit tests can be run directly using CMake/ctest
  • Test coverage - Comprehensive test suite includes:
    • LexerTests - Tokenization and lexer functionality
    • ParserTests - AST parsing and syntax analysis
    • CodeGenTests - RISC-V code generation
    • IntegrationTests - End-to-end compilation pipeline
    • PrimitivesTests - Basic data type handling
    • CompilationTests - Full compilation pipeline with register allocation verification
  • All tests passing - Verified on Windows with MinGW-LLVM toolchain
  • Test execution: cd src/gdscript/compiler/build && ctest --output-on-failure

Build System

  • MinGW-LLVM support - GDExtension can be built using MinGW with LLVM/Clang toolchain
  • Cross-platform builds - Build system supports both MSVC (with limitations) and MinGW-LLVM
  • CI/CD integration - Compiler is tested in CI via integration tests in GUT framework
    • Tests run in .github/workflows/unittests.ymlbuild job
    • Compiler is built as part of tests/CMakeLists.txt and linked into test ELF
    • Integration tests verify full compilation pipeline: GDScript → ELF → Sandbox execution

Register Allocation Testing

  • Register allocation tests - Comprehensive test coverage in test_compilation.cpp:
    • Basic compilation verification
    • Register allocation with 15+ variables (stress test)
    • Complex expression handling
    • Register spilling minimization
    • Register limit enforcement (max_registers <= 25)
    • Edge cases (empty functions, parameters, overlapping live ranges)
  • Integration tests - test_register_allocation.gd tests register allocation in real compilation scenarios
  • All compilation tests passing - 16 test cases covering register allocation and compilation pipeline

Testing Methodology

  • Unit tests (ctest) - For development/debugging of compiler internals
  • Integration tests (GUT) - For end-to-end verification in CI/CD
  • Both approaches - Unit tests for local development, integration tests for CI verification
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment