nightshade

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

commit 4f6cee9ee4b62275df8aa9038930a2673d6eb4f6
parent c9fe5a0e42eff86c6223a1d0380137a297075da9
Author: citbl <citbl@citbl.org>
Date:   Sat, 13 Jun 2026 21:33:03 +1000

rename sem to binder

Diffstat:
Asrc/binder.adb | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/binder.ads | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/nightshade.adb | 6+++---
Dsrc/sem.adb | 148-------------------------------------------------------------------------------
Dsrc/sem.ads | 92-------------------------------------------------------------------------------
5 files changed, 243 insertions(+), 243 deletions(-)

diff --git a/src/binder.adb b/src/binder.adb @@ -0,0 +1,148 @@ +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 : Scope_Ref; + S : Sem; + begin + Sc := new 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 : Symbol_Info; + Int_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_INT); + String_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_STRING); + Bool_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_BOOL); + Void_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_VOID); + Error_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_ERROR); + Print_Type : constant Type_Info_Ref := + new Type_Info' + (Kind => TY_FUNC, + Func => + (Return_Type => Void_Type, Params => new Type_List'(1 => String_Type))); + begin + Put_Line ("load std symbols"); + Info := (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 : Scope_Ref; + begin + Sc := new Scope'(Parent => S.Scope, Symbols => Symbols); + S.Scope := Sc; + end; + + ----------------------------- + -- scope contains or error -- + ----------------------------- + + procedure Scope_Contains_Or_Error + (Sc : Scope_Ref; Name : Unbounded_String; Kind : Symbol_Kind_Enum) + is + Info : 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 " + & Symbol_Kind_Enum'Image (Kind) + & " in scope."); + return; + else + raise Program_Error + with + "Symbol found in scope was not of expected type " + & Symbol_Kind_Enum'Image (Kind) + & " but is in fact " + & Symbol_Kind_Enum'Image (Info.Kind); + end if; + elsif Sc.Parent /= null then + 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; Callee : in Call_Stmt) is + begin + -- determine whether the callee exist in scope or bail with error + Put_Line ("scoping call wip"); + Scope_Contains_Or_Error (S.Scope, Callee.Name, SYM_FUNC); + null; + 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 Func_Decl) is + begin + -- go through statements and +scope var_decl and -scope calls + for Statement of Fn.Stmts loop + if Statement.Kind = Stmt_Call then + Put_Line ("scoping call"); + Scope_Call (S, Statement.Call); + 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 + 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 @@ -0,0 +1,92 @@ +with Parser; use Parser; + +with Ada.Containers.Indefinite_Hashed_Maps; +with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; +with Ada.Strings.Hash; + +package Binder is + + type Type_Info; + type Function_Info; + + type Type_Info_Ref is access all Type_Info; + type Function_Info_Ref is access all Function_Info; + + type Symbol_Kind_Enum is (SYM_FUNC, SYM_VAR, SYM_LET); + type Type_Kind_Enum is (TY_STRING, TY_INT, TY_FLOAT, TY_BOOL, TY_VOID, TY_FUNC, TY_ERROR); + + type Type_List is array (Positive range <>) of Type_Info_Ref; + type Type_List_Ref is access all Type_List; + + type Function_Info is record + Params : Type_List_Ref; + Return_Type : Type_Info_Ref; + end record; + + type Type_Info (Kind : Type_Kind_Enum := TY_ERROR) is record + case Kind is + when TY_FUNC => + Func : Function_Info; + + when others => + null; + end case; + end record; + + + -------------------------------- + -- symbol info ----------------- + -- made of kind and type info -- + -------------------------------- + + type Symbol_Info is record + Kind : Symbol_Kind_Enum; + Typ : Type_Info_Ref; + end record; + + ------------------------------------- + -- hashmap of String : Symbol_Info -- + ------------------------------------- + + package Symbols_Map is new + Ada.Containers.Indefinite_Hashed_Maps + (Key_Type => String, + Element_Type => Symbol_Info, -- symbol's info + Hash => Ada.Strings.Hash, + Equivalent_Keys => "="); + + ------------- + --- scope --- + ------------- + + type Scope; + + type Scope_Ref is access Scope; + + type Scope is record + Symbols : Symbols_Map.Map; + Parent : Scope_Ref; + end record; + + --------- + -- sem -- + --------- + + type Sem is record + Scope : 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 @@ -3,7 +3,7 @@ with Ada.Command_Line; use Ada.Command_Line; with Utils; with Lexer; with Parser; -with Sem; +with Binder; procedure Nightshade is begin @@ -29,9 +29,9 @@ begin Parser.Print_AST (P); declare - S : Sem.Sem := Sem.Init(P.Declarations); + S : Binder.Sem := Binder.Init(P.Declarations); begin - Sem.Analysis(S); + Binder.Analysis(S); end; end; end; diff --git a/src/sem.adb b/src/sem.adb @@ -1,148 +0,0 @@ -with Parser; use Parser; -with Ada.Containers.Indefinite_Vectors; -with Ada.Text_IO; use Ada.Text_IO; - -package body Sem is - - procedure Load_STD_Symbols (S : in out Sem); - - ---------- - -- init -- - ---------- - - function Init (AST : Declaration_Vectors.Vector) return Sem is - Symbols : Symbols_Map.Map; - Sc : Scope_Ref; - S : Sem; - begin - Sc := new 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 : Symbol_Info; - Int_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_INT); - String_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_STRING); - Bool_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_BOOL); - Void_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_VOID); - Error_Type : constant Type_Info_Ref := new Type_Info'(Kind => TY_ERROR); - Print_Type : constant Type_Info_Ref := - new Type_Info' - (Kind => TY_FUNC, - Func => - (Return_Type => Void_Type, Params => new Type_List'(1 => String_Type))); - begin - Put_Line ("load std symbols"); - Info := (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 : Scope_Ref; - begin - Sc := new Scope'(Parent => S.Scope, Symbols => Symbols); - S.Scope := Sc; - end; - - ----------------------------- - -- scope contains or error -- - ----------------------------- - - procedure Scope_Contains_Or_Error - (Sc : Scope_Ref; Name : Unbounded_String; Kind : Symbol_Kind_Enum) - is - Info : 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 " - & Symbol_Kind_Enum'Image (Kind) - & " in scope."); - return; - else - raise Program_Error - with - "Symbol found in scope was not of expected type " - & Symbol_Kind_Enum'Image (Kind) - & " but is in fact " - & Symbol_Kind_Enum'Image (Info.Kind); - end if; - elsif Sc.Parent /= null then - 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; Callee : in Call_Stmt) is - begin - -- determine whether the callee exist in scope or bail with error - Put_Line ("scoping call wip"); - Scope_Contains_Or_Error (S.Scope, Callee.Name, SYM_FUNC); - null; - 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 Func_Decl) is - begin - -- go through statements and +scope var_decl and -scope calls - for Statement of Fn.Stmts loop - if Statement.Kind = Stmt_Call then - Put_Line ("scoping call"); - Scope_Call (S, Statement.Call); - 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 - Put_Line ("scoping function"); - Scope_Func (S, Declaration.Func); - end if; - null; - end loop; - end Analysis; - -end Sem; diff --git a/src/sem.ads b/src/sem.ads @@ -1,92 +0,0 @@ -with Parser; use Parser; - -with Ada.Containers.Indefinite_Hashed_Maps; -with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; -with Ada.Strings.Hash; - -package Sem is - - type Type_Info; - type Function_Info; - - type Type_Info_Ref is access all Type_Info; - type Function_Info_Ref is access all Function_Info; - - type Symbol_Kind_Enum is (SYM_FUNC, SYM_VAR, SYM_LET); - type Type_Kind_Enum is (TY_STRING, TY_INT, TY_FLOAT, TY_BOOL, TY_VOID, TY_FUNC, TY_ERROR); - - type Type_List is array (Positive range <>) of Type_Info_Ref; - type Type_List_Ref is access all Type_List; - - type Function_Info is record - Params : Type_List_Ref; - Return_Type : Type_Info_Ref; - end record; - - type Type_Info (Kind : Type_Kind_Enum := TY_ERROR) is record - case Kind is - when TY_FUNC => - Func : Function_Info; - - when others => - null; - end case; - end record; - - - -------------------------------- - -- symbol info ----------------- - -- made of kind and type info -- - -------------------------------- - - type Symbol_Info is record - Kind : Symbol_Kind_Enum; - Typ : Type_Info_Ref; - end record; - - ------------------------------------- - -- hashmap of String : Symbol_Info -- - ------------------------------------- - - package Symbols_Map is new - Ada.Containers.Indefinite_Hashed_Maps - (Key_Type => String, - Element_Type => Symbol_Info, -- symbol's info - Hash => Ada.Strings.Hash, - Equivalent_Keys => "="); - - ------------- - --- scope --- - ------------- - - type Scope; - - type Scope_Ref is access Scope; - - type Scope is record - Symbols : Symbols_Map.Map; - Parent : Scope_Ref; - end record; - - --------- - -- sem -- - --------- - - type Sem is record - Scope : 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 Sem;