nightshade

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

commit 33a90a70e24e7c315805416802ce1b1f3beacb46
parent d9e2201d4d3e90264653d79e37d19250c9039adf
Author: citbl <citbl@citbl.org>
Date:   Sun, 14 Jun 2026 16:14:11 +1000

refac and undo returning scope

Diffstat:
Dsrc/binder.adb | 159-------------------------------------------------------------------------------
Dsrc/binder.ads | 29-----------------------------
Msrc/nightshade.adb | 6+++---
Asrc/scope.adb | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/scope.ads | 29+++++++++++++++++++++++++++++
5 files changed, 187 insertions(+), 191 deletions(-)

diff --git a/src/binder.adb b/src/binder.adb @@ -1,159 +0,0 @@ -with Parser; use Parser; -with Ada.Containers.Indefinite_Vectors; -with Ada.Text_IO; use Ada.Text_IO; - -package body Binder is - - procedure Load_STD_Symbols (S : in out Sem); - - ---------- - -- init -- - ---------- - - function Init (AST : Declaration_Vectors.Vector) return Sem is - Symbols : Symbols_Map.Map; - Sc : AST_Scope_Ref; - S : Sem; - begin - Sc := new AST_Scope'(Parent => null, Symbols => Symbols); - S := (Scope => Sc, AST => AST); - Load_STD_Symbols (S); - return S; - end Init; - - ----------------------- - -- load std in scope -- - ----------------------- - - procedure Load_STD_Symbols (S : in out Sem) is - Info : AST_Symbol_Info; - Int_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_INT); - String_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_STRING); - Bool_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_BOOL); - Void_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_VOID); - Error_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_ERROR); - Print_Type : constant AST_Type_Info_Ref := - new AST_Type_Info' - (Kind => TY_FUNC, - Func => - (Return_Type => Void_Type, Params => new AST_Type_List'(1 => String_Type))); - begin - Put_Line ("load std symbols"); - Info := - (Name => To_Unbounded_String ("print"), Kind => SYM_FUNC, Typ => Print_Type); - S.Scope.Symbols.Include ("print", Info); - end; - - -------------------------- - -- new scope from scope -- - -------------------------- - - procedure New_Scope_From_Scope (S : in out Sem) is - Symbols : Symbols_Map.Map; - Sc : AST_Scope_Ref; - begin - Sc := new AST_Scope'(Parent => S.Scope, Symbols => Symbols); - S.Scope := Sc; - end; - - ----------------------------- - -- scope contains or error -- - ----------------------------- - - -- recursive - function Scope_Contains_Or_Error - (Sc : AST_Scope_Ref; Name : Unbounded_String; Kind : AST_Symbol_Kind_Enum) - return AST_Scope_Ref - is - Info : AST_Symbol_Info; - begin - if Sc.Symbols.Contains (To_String (Name)) then - Info := Sc.Symbols.Element (To_String (Name)); - if Info.Kind = Kind then - Put_Line - ("Found " - & To_String (Name) - & " of kind " - & AST_Symbol_Kind_Enum'Image (Kind) - & " in scope."); - return Sc; - else - raise Program_Error - with - "Symbol found in scope was not of expected type " - & AST_Symbol_Kind_Enum'Image (Kind) - & " but is in fact " - & AST_Symbol_Kind_Enum'Image (Info.Kind); - end if; - elsif Sc.Parent /= null then - Put_Line ("Not found in current scope, looking in parent..."); - return Scope_Contains_Or_Error (Sc.Parent, Name, Kind); - else - raise Program_Error - with "Could not find symbol " & To_String (Name) & " in scope."; - end if; - end; - - --------------------- - -- scope func call -- - --------------------- - - function Scope_Call (S : in out Sem; Callee : in Call_Stmt) return AST_Scope_Ref is - Found_Scope : AST_Scope_Ref; - begin - -- determine whether the callee exist in scope or bail with error - Put_Line ("scoping call"); - Found_Scope := Scope_Contains_Or_Error (S.Scope, Callee.Name, SYM_FUNC); - return Found_Scope; - end; - - -------------------- - -- scope var decl -- - -------------------- - - procedure Scope_Var_Decl (S : in out Sem) is - begin - - -- TODO we do not yet add to scope, but we do not currently have - -- variables so this is a waste of time for now - - null; - end; - - ---------------- - -- scope func -- - ---------------- - - procedure Scope_Func (S : in out Sem; Fn : in out Func_Decl) is - Found_Scope : AST_Scope_Ref; - begin - -- entering function block scope - New_Scope_From_Scope (S); - - for Statement of Fn.Stmts loop - if Statement.Kind = Stmt_Call then - Put_Line ("scoping call"); - Found_Scope := Scope_Call (S, Statement.Call); - Statement.Scope := Found_Scope; - end if; - end loop; - end; - - -------------- - -- analysis -- - -------------- - - procedure Analysis (S : in out Sem) is - begin - for Declaration of S.AST loop - if Declaration.Kind = Function_Kind then - Declaration.Scope := S.Scope; - Put_Line ("scoping function"); - Scope_Func (S, Declaration.Func); - end if; - null; - end loop; - end Analysis; - -end Binder; - diff --git a/src/binder.ads b/src/binder.ads @@ -1,29 +0,0 @@ -with Ada.Containers.Indefinite_Hashed_Maps; -with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; -with Ada.Strings.Hash; -with Types; use Types; - -package Binder is - - --------- - -- sem -- - --------- - - type Sem is record - Scope : AST_Scope_Ref; - AST : Declaration_Vectors.Vector; - end record; - - ---------- - -- init -- - ---------- - - function Init (AST : Declaration_Vectors.Vector) return Sem; - - -------------- - -- analysis -- - -------------- - - procedure Analysis (S : in out Sem); - -end Binder; diff --git a/src/nightshade.adb b/src/nightshade.adb @@ -4,7 +4,7 @@ with Utils; with Types; with Lexer; with Parser; -with Binder; +with Scope; procedure Nightshade is begin @@ -30,9 +30,9 @@ begin Parser.Print_AST (P.Declarations); declare - BoundAST : Binder.Sem := Binder.Init (P.Declarations); + BoundAST : Scope.Sem := Scope.Init (P.Declarations); begin - Binder.Analysis (BoundAST); + Scope.Analysis (BoundAST); Parser.Print_AST (BoundAST.AST); end; end; diff --git a/src/scope.adb b/src/scope.adb @@ -0,0 +1,155 @@ +with Parser; use Parser; +with Ada.Containers.Indefinite_Vectors; +with Ada.Text_IO; use Ada.Text_IO; + +package body Scope is + + procedure Load_STD_Symbols (S : in out Sem); + + ---------- + -- init -- + ---------- + + function Init (AST : Declaration_Vectors.Vector) return Sem is + Symbols : Symbols_Map.Map; + Sc : AST_Scope_Ref; + S : Sem; + begin + Sc := new AST_Scope'(Parent => null, Symbols => Symbols); + S := (Scope => Sc, AST => AST); + Load_STD_Symbols (S); + return S; + end Init; + + ----------------------- + -- load std in scope -- + ----------------------- + + procedure Load_STD_Symbols (S : in out Sem) is + Info : AST_Symbol_Info; + Int_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_INT); + String_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_STRING); + Bool_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_BOOL); + Void_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_VOID); + Error_Type : constant AST_Type_Info_Ref := new AST_Type_Info'(Kind => TY_ERROR); + Print_Type : constant AST_Type_Info_Ref := + new AST_Type_Info' + (Kind => TY_FUNC, + Func => + (Return_Type => Void_Type, Params => new AST_Type_List'(1 => String_Type))); + begin + Put_Line ("load std symbols"); + Info := + (Name => To_Unbounded_String ("print"), Kind => SYM_FUNC, Typ => Print_Type); + S.Scope.Symbols.Include ("print", Info); + end; + + -------------------------- + -- new scope from scope -- + -------------------------- + + procedure New_Scope_From_Scope (S : in out Sem) is + Symbols : Symbols_Map.Map; + Sc : AST_Scope_Ref; + begin + Sc := new AST_Scope'(Parent => S.Scope, Symbols => Symbols); + S.Scope := Sc; + end; + + ----------------------------- + -- scope contains or error -- + ----------------------------- + + -- recursive + procedure Scope_Contains_Or_Error + (Sc : AST_Scope_Ref; Name : Unbounded_String; Kind : AST_Symbol_Kind_Enum) + is + Info : AST_Symbol_Info; + begin + if Sc.Symbols.Contains (To_String (Name)) then + Info := Sc.Symbols.Element (To_String (Name)); + if Info.Kind = Kind then + Put_Line + ("Found " + & To_String (Name) + & " of kind " + & AST_Symbol_Kind_Enum'Image (Kind) + & " in scope."); + return; + else + raise Program_Error + with + "Symbol found in scope was not of expected type " + & AST_Symbol_Kind_Enum'Image (Kind) + & " but is in fact " + & AST_Symbol_Kind_Enum'Image (Info.Kind); + end if; + elsif Sc.Parent /= null then + Put_Line ("Not found in current scope, looking in parent..."); + Scope_Contains_Or_Error (Sc.Parent, Name, Kind); + else + raise Program_Error + with "Could not find symbol " & To_String (Name) & " in scope."; + end if; + end; + + --------------------- + -- scope func call -- + --------------------- + + procedure Scope_Call (S : in out Sem; Func_Call : in Call_Stmt) is + begin + -- determine whether the callee exist in scope or bail with error + Put_Line ("scoping call"); + Scope_Contains_Or_Error (S.Scope, Func_Call.Name, SYM_FUNC); + end; + + -------------------- + -- scope var decl -- + -------------------- + + procedure Scope_Var_Decl (S : in out Sem) is + begin + + -- TODO we do not yet add to scope, but we do not currently have + -- variables so this is a waste of time for now + + null; + end; + + ---------------- + -- scope func -- + ---------------- + + procedure Scope_Func (S : in out Sem; Fn : in out Func_Decl) is + Found_Scope : AST_Scope_Ref; + begin + -- entering function block scope + New_Scope_From_Scope (S); + + for Statement of Fn.Stmts loop + if Statement.Kind = Stmt_Call then + Put_Line ("scoping call"); + Scope_Call (S, Statement.Call); + Statement.Scope := S.Scope; + end if; + end loop; + end; + + -------------- + -- analysis -- + -------------- + + procedure Analysis (S : in out Sem) is + begin + for Declaration of S.AST loop + if Declaration.Kind = Function_Kind then + Declaration.Scope := S.Scope; + Put_Line ("scoping function"); + Scope_Func (S, Declaration.Func); + end if; + null; + end loop; + end Analysis; + +end Scope; diff --git a/src/scope.ads b/src/scope.ads @@ -0,0 +1,29 @@ +with Ada.Containers.Indefinite_Hashed_Maps; +with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; +with Ada.Strings.Hash; +with Types; use Types; + +package Scope is + + --------- + -- sem -- + --------- + + type Sem is record + Scope : AST_Scope_Ref; + AST : Declaration_Vectors.Vector; + end record; + + ---------- + -- init -- + ---------- + + function Init (AST : Declaration_Vectors.Vector) return Sem; + + -------------- + -- analysis -- + -------------- + + procedure Analysis (S : in out Sem); + +end Scope;