feat: compile Endor await expressions through the source pipeline

This commit is contained in:
2026-10-23 20:14:15 +08:00
parent 16816c38c7
commit 8a2135897e
8 changed files with 39 additions and 6 deletions
+3 -1
View File
@@ -332,7 +332,9 @@ impl Builder {
binding,
});
}
ExprKind::Unary { operand, .. } => self.expression(operand, globals)?,
ExprKind::Unary { operand, .. } | ExprKind::Await { operand } => {
self.expression(operand, globals)?
}
ExprKind::Binary { left, right, .. } => {
self.expression(left, globals)?;
self.expression(right, globals)?;
+4
View File
@@ -300,6 +300,10 @@ impl<'a> Emitter<'a> {
}
self.emit(Opcode::Call, arguments.len())?;
}
ExprKind::Await { operand } => {
self.expression(operand)?;
self.simple(Opcode::Await);
}
ExprKind::Member { object, name } => {
self.expression(object)?;
self.emit(Opcode::LoadAttr, self.name_index(&name.text))?;
+1
View File
@@ -35,6 +35,7 @@ module Endor {
| Number(string spelling)
| String(string value)
| Symbol(Name name)
| Await(Expr operand)
| Unary(UnaryOp operation, Expr operand)
| Binary(BinaryOp operation, Expr left, Expr right)
| Member(Expr object, Name name)
+18 -2
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:endor:ast:sha256:ad2ac52943dd26e08395c0d2698861da98bb89c360241c4712c769de86709fd0",
"$id": "urn:endor:ast:sha256:c7c10c6a61158810fa55044f1aa79f3558ac18ca3be59cbf7f2499b5add8df5b",
"$ref": "#/$defs/AstDocument",
"$defs": {
"Span": {
@@ -27,7 +27,7 @@
"type": "object",
"properties": {
"schema": {
"const": "urn:endor:ast:sha256:ad2ac52943dd26e08395c0d2698861da98bb89c360241c4712c769de86709fd0"
"const": "urn:endor:ast:sha256:c7c10c6a61158810fa55044f1aa79f3558ac18ca3be59cbf7f2499b5add8df5b"
},
"root": {
"$ref": "#/$defs/AstRoot"
@@ -591,6 +591,22 @@
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": {
"const": "Await"
},
"data": {
"$ref": "#/$defs/Expr"
}
},
"required": [
"kind",
"data"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
+5 -2
View File
@@ -1,6 +1,6 @@
// Generated by scripts/generate_ast.py from Endor.asdl. Do not edit.
export const AST_SCHEMA_ID = "urn:endor:ast:sha256:ad2ac52943dd26e08395c0d2698861da98bb89c360241c4712c769de86709fd0" as const;
export const AST_SCHEMA_ID = "urn:endor:ast:sha256:c7c10c6a61158810fa55044f1aa79f3558ac18ca3be59cbf7f2499b5add8df5b" as const;
export interface Span { start: number; end: number; }
export type AstDocument = { schema: typeof AST_SCHEMA_ID; root: AstRoot; };
export type AstRoot = { kind: "Module"; data: Program; } | { kind: "Expression"; data: Expr; } | { kind: "Interactive"; data: InteractiveInput; };
@@ -20,7 +20,7 @@ export type MemberAssignment = { object: Expr; name: Name; value: Expr; span: Sp
export type ReturnStatement = { value?: Expr | null; span: Span; };
export type InteractiveInput = { statements: Array<Stmt>; span: Span; };
export type Expr = { kind: ExprKind; span: Span; };
export type ExprKind = { kind: "Name"; data: string; } | { kind: "Number"; data: string; } | { kind: "String"; data: string; } | { kind: "Symbol"; data: Name; } | { kind: "Unary"; data: { operation: UnaryOp; operand: Expr; }; } | { kind: "Binary"; data: { operation: BinaryOp; left: Expr; right: Expr; }; } | { kind: "Member"; data: { object: Expr; name: Name; }; } | { kind: "Call"; data: { callee: Expr; arguments: Array<Expr>; }; };
export type ExprKind = { kind: "Name"; data: string; } | { kind: "Number"; data: string; } | { kind: "String"; data: string; } | { kind: "Symbol"; data: Name; } | { kind: "Await"; data: Expr; } | { kind: "Unary"; data: { operation: UnaryOp; operand: Expr; }; } | { kind: "Binary"; data: { operation: BinaryOp; left: Expr; right: Expr; }; } | { kind: "Member"; data: { object: Expr; name: Name; }; } | { kind: "Call"; data: { callee: Expr; arguments: Array<Expr>; }; };
export type UnaryOp = "Negate";
export type BinaryOp = "Add" | "Subtract" | "Multiply" | "Divide";
export interface Visitor {
@@ -192,6 +192,9 @@ break;
case "Symbol":
walkName(node.data, visitor);
break;
case "Await":
walkExpr(node.data, visitor);
break;
case "Unary":
walkUnaryOp(node.data.operation, visitor);
walkExpr(node.data.operand, visitor);
+2 -1
View File
@@ -3,7 +3,7 @@
use super::Spanned;
use crate::Span;
pub const AST_SCHEMA_ID: &str =
"urn:endor:ast:sha256:ad2ac52943dd26e08395c0d2698861da98bb89c360241c4712c769de86709fd0";
"urn:endor:ast:sha256:c7c10c6a61158810fa55044f1aa79f3558ac18ca3be59cbf7f2499b5add8df5b";
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AstDocument {
@@ -234,6 +234,7 @@ pub enum ExprKind {
Number(String),
String(String),
Symbol(Name),
Await(Box<Expr>),
Unary {
operation: UnaryOp,
operand: Box<Expr>,
+3
View File
@@ -316,6 +316,9 @@ pub fn walk_expr_kind<V: Visitor + ?Sized>(
ExprKind::Symbol(value) => {
visitor.visit_name(value)?;
}
ExprKind::Await(value) => {
visitor.visit_expr(value)?;
}
ExprKind::Unary {
operation, operand, ..
} => {
+3
View File
@@ -146,6 +146,9 @@ peg::parser! {
left:(@) star() right:@ { binary(left, BinaryOp::Multiply, right) }
left:(@) slash() right:@ { binary(left, BinaryOp::Divide, right) }
--
start:keyword("await") operand:@ {
Expr { span: start.through(operand.span), kind: ExprKind::Await { operand: Box::new(operand) } }
}
start:minus() operand:@ {
Expr { span: start.through(operand.span), kind: ExprKind::Unary { operation: UnaryOp::Negate, operand: Box::new(operand) } }
}