commit 86b0e2573b2d7131316989f34509c4788274a6f5
parent cee9de1c5073c352838dd65b7bd51d445369492f
Author: citbl <citbl@citbl.org>
Date: Sun, 7 Jun 2026 23:17:09 +1000
parsing wip
Diffstat:
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