nightshade

The nightshade programming language, compiler and tools (WIP)
Log | Files | Refs

commit 86b0e2573b2d7131316989f34509c4788274a6f5
parent cee9de1c5073c352838dd65b7bd51d445369492f
Author: citbl <citbl@citbl.org>
Date:   Sun,  7 Jun 2026 23:17:09 +1000

parsing wip

Diffstat:
Msrc/lexer.adb | 12++++--------
Msrc/lexer.ads | 1+
Msrc/parser.adb | 84++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/parser.ads | 35+++++++++++++++++++----------------
4 files changed, 77 insertions(+), 55 deletions(-)

diff --git a/src/lexer.adb b/src/lexer.adb @@ -68,9 +68,7 @@ package body Lexer is Col => L.Col); Add_Token (L, T); end if; - if Is_Space (C) - or Is_Line_Terminator (C) - or C = Character'Val (9) -- \t + if Is_Space (C) or Is_Line_Terminator (C) or C = Character'Val (9) -- \t then Nudge (L); else @@ -279,6 +277,8 @@ package body Lexer is TK := L_Brace; elsif C = '}' then TK := R_Brace; + elsif C = ',' then + TK := Comma; elsif C = ':' then if C2 = ':' then TK := ColonColon; @@ -296,11 +296,7 @@ package body Lexer is -- & Integer'Image (Character'Pos (C))); end if; - T := - (Kind => TK, - Lexeme => To_Unbounded_String (""), - Line => Line, - Col => Col); + T := (Kind => TK, Lexeme => To_Unbounded_String (""), Line => Line, Col => Col); Nudge (L); return T; end Next_Token; diff --git a/src/lexer.ads b/src/lexer.ads @@ -20,6 +20,7 @@ package Lexer is R_Brace, ColonColon, Colon, + Comma, Separator, Keyword, Unknown, diff --git a/src/parser.adb b/src/parser.adb @@ -60,33 +60,48 @@ package body Parser is raise Program_Error with "Consume: Token out of bounds"; end Consume; - function Parse_Expr (P : in out Parser) return Expr is + function Parse_Expr (P : in out Parser) return Expr_Ref is T : Token; + E : Expr_Ref; begin - null; -- TODO parse expr + T := Match (P, Str_Literal); + E := new Expr'(Kind => String_Literal, Lit_Str => T.Lexeme); + return E; end Parse_Expr; -- TODO parse func call statement - function Parse_Call_Statement (P : in out Parser) return Call_Statement is - T : Token; - Name : Unbounded_String; + function Parse_Call_Statement (P : in out Parser) return Stmt_Ref is + T : Token; + Name : Unbounded_String; + E : Expr_Ref; + Expressions : Expr_Vectors.Vector; + CS : Call_Stmt; + ST : Stmt_Ref; begin - T := Expect (P, Ident); + T := Match (P, Ident); Name := T.Lexeme; - T := Expect (P, L_Paren); + T := Match (P, L_Paren); loop T := Peek (P); exit when T.Kind = EOF or T.Kind = R_Paren; + E := Parse_Expr (P); + Expressions.Append (E); + T := Peek (P); + exit when T.Kind /= Comma; end loop; + T := Match (P, R_Paren); + CS := Call_Stmt'(Name => Name, Params => Expressions); + ST := new Stmt'(Kind => Stmt_call, Call => CS); + return ST; end; -- parse stmt - function Parse_Statement (P : in out Parser) return Statement is + function Parse_Statement (P : in out Parser) return Stmt_Ref is T : Token; begin @@ -95,9 +110,8 @@ package body Parser is exit when T.Kind = EOF or (T.Kind = Keyword and T.Lexeme = "end"); if T.Kind = Ident and Peek2 (P).Kind = L_Paren then - -- func call - Parse_Call_Statement (P); - end if; -- TODO support other statement kinds + return Parse_Call_Statement (P); + end if; end loop; @@ -105,47 +119,55 @@ package body Parser is -- parse func decl - function Parse_Func_Decl (P : in out Parser) return Node_Ref is + function Parse_Func_Decl (P : in out Parser) return Decl is T : Token; - Name_Token : Token; + Name : Unbounded_String; + Param_Name : Unbounded_String; + Param_Kind : Unbounded_String; Public : Boolean := false; Func : Func_Decl; Stmts : Stmt_Vectors.Vector; - Stmt : Statement; + Pa : Param; + Params : Param_Vectors.Vector; + S : Statement; begin T := Consume (P); -- fx if T.Lexeme = fx then Public := true; end if; - Name_Token := Match (P, Ident); + Name := Match (P, Ident).Lexeme; Match (P, L_Paren); -- ( + + -- func decl params + loop - -- params T := Peek (P); exit when T.Kind = EOF or T.Kind = R_Paren; - if T.Kind = Comma then - Consume (P); - goto continue; - end if; - Expect (P, Ident); -- type of param - Expect (P, Ident); -- name of param - - <<continue>> + Match (P, Ident); -- type of param + Match (P, Ident); -- name of param + Pa := Param'(Name => Param_Name, Kind => Param_Kind); + Params.Append (Pa); + T := Peek (P); + exit when T.Kind /= Comma; end loop; - Expect (P, R_Paren); - Expect (P, ColonColon); + Match (P, R_Paren); -- TODO return kind + Match (P, ColonColon); - -- parse statements + -- func decl statements loop T := Peek (P); - exit when T.Kind = EOF or T.Lexeme = "end"; - - Stmt := Parse_Statement (P); - Stmts.Append (Stmt); + exit when T.Kind = EOF or (T.Kind = Keyword and T.Lexeme = "end"); + S := Parse_Statement (P); + Stmts.Append (S); end loop; + return + Decl + (Kind => Function_Kind, + Func => Func_Decl (Name => Name, Params => Params, Return_Kind => "", Stmts => Stmts)); + end Parse_Func_Decl; -- parse program diff --git a/src/parser.ads b/src/parser.ads @@ -31,12 +31,12 @@ package Parser is NODE_TYPE, NODE_BINARY_EXPR, NODE_UNARY_EXPR, - NODE_EXPR_STATEMENT, + NODE_EXPR_Stmt, NODE_SUBSCRIPT_EXPR, NODE_IF, NODE_WHILE, NODE_FOR, - NODE_EMPTY_STATEMENT, + NODE_EMPTY_Stmt, NODE_UNKNOWN); package Nodes_Vector is new @@ -50,14 +50,26 @@ package Parser is package Param_Vectors is new Ada.Containers.Vectors (Index_Type => Natural, Element_Type => Param); - type Statement_Kind is (Stmt_Call); + type Expr; + + type Expr_Ref is access Expr; + + package Expr_Vectors is new + Ada.Containers.Indefinite_Vectors (Index_Type => Natural, Element_Type => Expr_Ref); + + type Stmt_Kind is (Stmt_Call); type Call_Stmt is record Name : Unbounded_String; - Params : Param_Vectors.Vector; + Params : Expr_Vectors.Vector; end record; - type Statement (Kind : Statement_Kind) is record + type Call_Expr is record + Callee : Unbounded_String; + Params : Expr_Vectors.Vector; + end record; + + type Stmt (Kind : Stmt_Kind) is record case Kind is when Stmt_Call => Call : Call_Stmt; @@ -73,20 +85,11 @@ package Parser is end case; end record; - type Expr; - type Expr_Ref is access Expr; + type Stmt_Ref is access Stmt; package Stmt_Vectors is new - Ada.Containers.Indefinite_Vectors (Index_Type => Natural, Element_Type => Statement); - - package Expr_Vectors is new - Ada.Containers.Indefinite_Vectors (Index_Type => Natural, Element_Type => Expr_Ref); - - type Call_Expr is record - Callee : Unbounded_String; - Params : Expr_Vectors.Vector; - end record; + Ada.Containers.Indefinite_Vectors (Index_Type => Natural, Element_Type => Stmt_Ref); type Expr_Kind is (Expr_Call, String_Literal); type Expr (Kind : Expr_Kind := Expr_Call) is record