AST (Abstract Syntax Tree)¶
L'AST de GMX représente la structure complète d'un fichier .gmx parsé. Tous les types sont définis dans internal/compiler/ast/ast.go.
Structure Racine¶
GMXFile¶
type GMXFile struct {
Models []*ModelDecl
Services []*ServiceDecl
Script *ScriptBlock
Template *TemplateBlock
Style *StyleBlock
}
C'est le nœud racine qui contient toutes les sections d'un fichier .gmx.
Section Models¶
ModelDecl¶
Représente model Task { ... }.
FieldDecl¶
Représente title: string @min(3) @max(255).
Types supportés : uuid, string, int, float, bool, datetime, ou nom de modèle (relation).
Annotation¶
type Annotation struct {
Name string // "pk", "default", "min", "email", etc.
Args map[string]string // Arguments nommés ou simples
}
Exemples :
| GMX | Name | Args |
|---|---|---|
@pk |
"pk" |
{} |
@default(false) |
"default" |
{"_": "false"} |
@min(3) |
"min" |
{"_": "3"} |
@relation(references: [id]) |
"relation" |
{"references": "id"} |
Helper : SimpleArg() retourne la valeur pour une annotation simple.
Section Services¶
ServiceDecl¶
type ServiceDecl struct {
Name string
Provider string
Fields []*ServiceField
Methods []*ServiceMethod
}
Représente service Database { provider: "sqlite"; ... }.
ServiceField¶
Représente url: string @env("DATABASE_URL").
ServiceMethod¶
Représente func send(to: string, subject: string, body: string) error.
Section Script¶
ScriptBlock¶
type ScriptBlock struct {
Source string // Raw source (fallback)
Funcs []*FuncDecl // Parsed functions (nil if parsing failed)
StartLine int // Line offset for source maps
}
FuncDecl¶
Représente func toggleTask(id: uuid) error { ... }.
Param¶
Statements¶
Tous les statements implémentent l'interface :
LetStmt¶
Représente let task = try Task.find(id) ou const x = 5.
AssignStmt¶
Représente task.done = !task.done.
ReturnStmt¶
IfStmt¶
type IfStmt struct {
Condition Expression
Consequence []Statement
Alternative []Statement // nil si pas de 'else'
Line int
}
ExprStmt¶
Utilisé pour les appels de fonction utilisés comme statements.
Expressions¶
Toutes les expressions implémentent :
Ident¶
Représente une variable : task, count, etc.
Littéraux¶
type IntLit struct {
Value string
Line int
}
type FloatLit struct {
Value string
Line int
}
type StringLit struct {
Value string
Parts []StringPart // Pour interpolation
Line int
}
type BoolLit struct {
Value bool
Line int
}
StringPart (Interpolation)¶
Pour "Hello, {name}!" :
Parts: []StringPart{
{IsExpr: false, Text: "Hello, "},
{IsExpr: true, Expr: &Ident{Name: "name"}},
{IsExpr: false, Text: "!"},
}
UnaryExpr¶
Représente !task.done ou -count.
BinaryExpr¶
type BinaryExpr struct {
Left Expression
Op string // "+", "==", "&&", etc.
Right Expression
Line int
}
Représente count + 1, task.done == true, etc.
CallExpr¶
Représente Task.find(id) ou processData(x, y).
MemberExpr¶
Représente task.title, user.email, Task.find, etc.
TryExpr¶
Représente try Task.find(id).
RenderExpr¶
Représente render(task) ou render(task, user).
ErrorExpr¶
Représente error("Title cannot be empty").
CtxExpr¶
Représente ctx.User, ctx.Tenant, etc.
StructLit¶
Représente Task{title: "New", done: false}.
Section Template¶
TemplateBlock¶
Contient le HTML brut avec syntaxe Go template.
Section Style¶
StyleBlock¶
Interface Node¶
Tous les nœuds implémentent :
Utilisé pour le debugging et les messages d'erreur.
Exemple Complet¶
GMX :
model Task {
id: uuid @pk @default(uuid_v4)
title: string @min(3)
done: bool
}
<script>
func toggleTask(id: uuid) error {
let task = try Task.find(id)
task.done = !task.done
try task.save()
return render(task)
}
</script>
AST Partiel :
&ast.GMXFile{
Models: []*ast.ModelDecl{
{
Name: "Task",
Fields: []*ast.FieldDecl{
{
Name: "id",
Type: "uuid",
Annotations: []*ast.Annotation{
{Name: "pk", Args: map[string]string{}},
{Name: "default", Args: map[string]string{"_": "uuid_v4"}},
},
},
{
Name: "title",
Type: "string",
Annotations: []*ast.Annotation{
{Name: "min", Args: map[string]string{"_": "3"}},
},
},
{Name: "done", Type: "bool", Annotations: nil},
},
},
},
Script: &ast.ScriptBlock{
Source: "func toggleTask(id: uuid) error { ... }",
Funcs: []*ast.FuncDecl{
{
Name: "toggleTask",
Params: []*ast.Param{
{Name: "id", Type: "uuid"},
},
ReturnType: "error",
Body: []ast.Statement{
&ast.LetStmt{
Name: "task",
Value: &ast.TryExpr{
Expr: &ast.CallExpr{
Function: &ast.MemberExpr{
Object: &ast.Ident{Name: "Task"},
Property: "find",
},
Args: []ast.Expression{
&ast.Ident{Name: "id"},
},
},
},
},
&ast.AssignStmt{
Target: &ast.MemberExpr{
Object: &ast.Ident{Name: "task"},
Property: "done",
},
Value: &ast.UnaryExpr{
Op: "!",
Operand: &ast.MemberExpr{
Object: &ast.Ident{Name: "task"},
Property: "done",
},
},
},
&ast.ExprStmt{
Expr: &ast.TryExpr{
Expr: &ast.CallExpr{
Function: &ast.MemberExpr{
Object: &ast.Ident{Name: "task"},
Property: "save",
},
Args: []ast.Expression{},
},
},
},
&ast.ReturnStmt{
Value: &ast.RenderExpr{
Args: []ast.Expression{
&ast.Ident{Name: "task"},
},
},
},
},
},
},
},
}
Prochaines Étapes¶
- Lexer & Parser — Comment l'AST est construit
- Generator — Comment l'AST est utilisé
- Script Transpiler — Transpilation de l'AST script