Skip to content

Grammar

This is the formal grammar of Ḍād in EBNF notation (draft 0). The lexical rules are described in the specification, §2.

(* Ḍād (ضاد) grammar — draft 0
   Notation: ISO-ish EBNF. Keywords appear in Arabic; Latin punctuation forms shown,
   Arabic forms (، ؛ ؟ ؟. ؟؟) are equivalent tokens produced by the lexer.
   NL = newline (statement terminator). Newlines inside () [] are ignored. *)

file            = { NL } , { import , terms } , { decl , terms } ;
terms           = NL | ";" , { NL } ;

import          = "استورد" , ident , { "," , ident } , "من" , string ;

decl            = [ "خاص" ] , ( func_decl | type_decl | enum_decl | contract_decl
                              | extension_decl | table_decl | route_decl
                              | component_decl | binding ) ;

(* ---------- declarations ---------- *)
binding         = ( "ثابت" | "متغير" ) , ident , [ ":" , type ] , "=" , expr ;

func_decl       = [ "خادم" ] , "دالة" , ident , params , [ ":" , type ] , body ;
params          = "(" , [ param , { "," , param } ] , ")" ;
param           = ident , ":" , type , [ "=" , expr ] ;
body            = block | "=" , expr ;

type_decl       = "نوع" , ident , params , [ ":" , type_list ] , [ member_block ] ;
enum_decl       = "تعداد" , ident , "{" , { NL } , { variant , terms } , "}" ;
variant         = ident , [ params ] ;
contract_decl   = "عقد" , ident , "{" , { NL } , { func_sig , terms } , "}" ;
func_sig        = "دالة" , ident , params , [ ":" , type ] ;
extension_decl  = "امتداد" , type , member_block ;
member_block    = "{" , { NL } , { decl , terms } , "}" ;

table_decl      = "جدول" , ident , "{" , { NL } , { field , terms } , "}" ;
field           = ident , ( ":" , type , [ "=" , expr ] | "=" , expr ) ;

route_decl      = "مسار" , http_verb , string , [ params ] , body ;
http_verb       = ident ;   (* contextual: جلب أرسل حدث احذف *)

component_decl  = "مكون" , ident , params , block ;

(* ---------- types ---------- *)
type            = base_type , [ "?" ] ;
base_type       = ident , [ "<" , type_list , ">" ]
                | "[" , type , [ ":" , type ] , "]"          (* list / map *)
                | "(" , [ type_list ] , ")" , "=>" , type ;  (* function *)
type_list       = type , { "," , type } ;

(* ---------- statements ---------- *)
block           = "{" , { NL } , { stmt , terms } , [ stmt ] , "}" ;
stmt            = binding
                | "حالة" , ident , [ ":" , type ] , "=" , expr
                | "لكل" , ident , ( "في" , expr
                                  | "من" , expr , ( "إلى" | "حتى" ) , expr , [ "بخطوة" , expr ] ) , block
                | "طالما" , expr , block
                | "أرجع" , [ expr ]
                | "توقف" | "تابع"
                | "ارفع" , expr
                | assignment
                | expr ;
assignment      = postfix , ( "=" | "+=" | "-=" | "*=" | "/=" ) , expr ;

(* ---------- expressions (lowest → highest precedence) ---------- *)
expr            = coalesce ;
coalesce        = or_expr , { "??" , or_expr } ;
or_expr         = and_expr , { ( "أو" | "||" ) , and_expr } ;
and_expr        = equality , { ( "و" | "&&" ) , equality } ;
equality        = comparison , { ( "==" | "!=" ) , comparison } ;
comparison      = range , { ( "<" | ">" | "<=" | ">=" ) , range }
                | range , "هو" , type                       (* type test *) ;
range           = additive , [ ( ".." ) , additive ] ;
additive        = multiplicative , { ( "+" | "-" ) , multiplicative } ;
multiplicative  = cast , { ( "*" | "/" | "%" ) , cast } ;
cast            = unary , [ "ك" , type ] ;
unary           = ( "-" | "ليس" | "!" ) , unary | postfix ;
postfix         = primary , { call_suffix | "." , ident | "?." , ident | "[" , expr , "]" } ;
call_suffix     = args , [ lambda ] | lambda ;              (* trailing lambda *)
args            = "(" , [ arg , { "," , arg } ] , ")" ;
arg             = [ ident , ":" ] , expr ;

primary         = number | string | "صح" | "خطأ" | "عدم" | "هذا"
                | "هو"                                       (* implicit lambda param *)
                | ident
                | "(" , expr , ")"
                | "[" , [ expr , { "," , expr } ] , "]"      (* list literal *)
                | "[" , ( ":" | expr , ":" , expr , { "," , expr , ":" , expr } ) , "]"
                | if_expr | match_expr | try_expr | lambda ;

if_expr         = "إذا" , expr , block , [ "وإلا" , ( if_expr | block ) ] ;
match_expr      = "طابق" , expr , "{" , { NL } , { case , terms } , "}" ;
case            = pattern , "=>" , ( expr | block ) ;
pattern         = "_" | literal | ident , [ "(" , [ ident , { "," , ident } ] , ")" ] ;
try_expr        = "حاول" , block , "التقط" , ident , block ;
lambda          = "{" , [ ident , { "," , ident } , "=>" ] , { NL } , { stmt , terms } , [ stmt ] , "}" ;

(* ---------- lexical (see SPEC §2) ---------- *)
ident           = letter , { letter | digit | "_" } ;
number          = digits , [ ( "." | "٫" ) , digits ] ;   (* one digit script per literal *)
string          = '"' , { char | interpolation } , '"'
                | "«" , { char | interpolation } , "»" ;
interpolation   = "{" , expr , "}" ;