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.
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.
type ModelDecl struct {
Name string
Fields []*FieldDecl
}Représente model Task { ... }.
type FieldDecl struct {
Name string
Type string
Annotations []*Annotation
}Représente title: string @min(3) @max(255).
Types supportés : uuid, string, int, float, bool, datetime, ou nom de modèle (relation).
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.
ann := &Annotation{Name: "min", Args: {"_": "3"}}
ann.SimpleArg() // → "3"type ServiceDecl struct {
Name string
Provider string
Fields []*ServiceField
Methods []*ServiceMethod
}Représente service Database { provider: "sqlite"; ... }.
type ServiceField struct {
Name string
Type string
EnvVar string
Annotations []*Annotation
}Représente url: string @env("DATABASE_URL").
type ServiceMethod struct {
Name string
Params []*Param
ReturnType string
}Représente func send(to: string, subject: string, body: string) error.
type ScriptBlock struct {
Source string // Raw source (fallback)
Funcs []*FuncDecl // Parsed functions (nil if parsing failed)
StartLine int // Line offset for source maps
}type FuncDecl struct {
Name string
Params []*Param
ReturnType string
Body []Statement
Line int
}Représente func toggleTask(id: uuid) error { ... }.
type Param struct {
Name string
Type string
}Tous les statements implémentent l'interface :
type Statement interface {
Node
statementNode()
}type LetStmt struct {
Name string
Value Expression
Const bool // true si 'const'
Line int
}Représente let task = try Task.find(id) ou const x = 5.
type AssignStmt struct {
Target Expression // Ident ou MemberExpr
Value Expression
Line int
}Représente task.done = !task.done.
type ReturnStmt struct {
Value Expression // nil pour 'return'
Line int
}type IfStmt struct {
Condition Expression
Consequence []Statement
Alternative []Statement // nil si pas de 'else'
Line int
}type ExprStmt struct {
Expr Expression
Line int
}Utilisé pour les appels de fonction utilisés comme statements.
Toutes les expressions implémentent :
type Expression interface {
Node
expressionNode()
}type Ident struct {
Name string
Line int
}Représente une variable : task, count, etc.
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
}type StringPart struct {
IsExpr bool
Text string // Si !IsExpr
Expr Expression // Si IsExpr
}Pour "Hello, {name}!" :
Parts: []StringPart{
{IsExpr: false, Text: "Hello, "},
{IsExpr: true, Expr: &Ident{Name: "name"}},
{IsExpr: false, Text: "!"},
}type UnaryExpr struct {
Op string // "!", "-"
Operand Expression
Line int
}Représente !task.done ou -count.
type BinaryExpr struct {
Left Expression
Op string // "+", "==", "&&", etc.
Right Expression
Line int
}Représente count + 1, task.done == true, etc.
type CallExpr struct {
Function Expression // Ident ou MemberExpr
Args []Expression
Line int
}Représente Task.find(id) ou processData(x, y).
type MemberExpr struct {
Object Expression
Property string
Line int
}Représente task.title, user.email, Task.find, etc.
type TryExpr struct {
Expr Expression
Line int
}Représente try Task.find(id).
type RenderExpr struct {
Args []Expression
Line int
}Représente render(task) ou render(task, user).
type ErrorExpr struct {
Message Expression
Line int
}Représente error("Title cannot be empty").
type CtxExpr struct {
Field string
Line int
}Représente ctx.User, ctx.Tenant, etc.
type StructLit struct {
TypeName string
Fields map[string]Expression
Line int
}Représente Task{title: "New", done: false}.
type TemplateBlock struct {
Source string // Raw HTML template
}Contient le HTML brut avec syntaxe Go template.
type StyleBlock struct {
Source string // Raw CSS
Scoped bool // true si '<style scoped>'
}Tous les nœuds implémentent :
type Node interface {
TokenLiteral() string
}Utilisé pour le debugging et les messages d'erreur.
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"},
},
},
},
},
},
},
},
}- Lexer & Parser — Comment l'AST est construit
- Generator — Comment l'AST est utilisé
- Script Transpiler — Transpilation de l'AST script