nightshade

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

nightshade.adb (3636B)



with Ada.Environment_Variables;
with Ada.Text_IO;           use Ada.Text_IO;
with Ada.Command_Line;      use Ada.Command_Line;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Utils;
with Types;
with Lexer;
with Parser;
with AST_Scoper;
with AST_Typer;
with Gen;
with GNAT.OS_Lib;           use GNAT.OS_Lib;

procedure Nightshade is
begin
   if Argument_Count < 1 then
      Put_Line ("usage: nightshade <filename>");
      return;
   end if;

   declare
      File_Name     : constant String := Argument (1);
      File_Contents : constant String := Utils.Read_File (File_Name);
      Src_Ref       : constant Types.Source_Ref := new String'(File_Contents);
      File_Name_Ref : constant Types.File_Name_Ref := new String'(File_Name);
      L             : Lexer.Lexer := Lexer.Init (File_Name_Ref, Src_Ref);
   begin
      Lexer.Lex (L);
      Lexer.Print_Tokens (L);

      declare
         P : Parser.Parser := Parser.Init (File_Name_Ref, Src_Ref, L.Tokens);
      begin
         Parser.Parse (P);
         Utils.Print_AST (P.AST);

         declare
            Scoper : AST_Scoper.Scoper := AST_Scoper.Init (P.AST);
         begin
            AST_Scoper.Analysis (Scoper);
            Utils.Print_AST (Scoper.Scoped_AST);
            declare
               TypedAST : AST_Typer.Typer := AST_Typer.Init (P.AST);
            begin
               AST_Typer.Type_Check (TypedAST);

               declare
                  Generator : Gen.Generator := Gen.Init (P.AST);

               begin
                  Gen.Gen_IR (Generator);

                  declare
                     F        : File_Type;
                     QBE_Args : Argument_List :=
                       (1 => new String'("-o"),
                        2 => new String'("tmp/out.s"),
                        3 => new String'("tmp/main.ssa"));
                     CC_Args  : Argument_List := (1 => new String'("tmp/out.s"));
                     Status   : Integer;
                     Success  : Boolean;
                  begin
                     Create (F, Out_File, "tmp/main.ssa");
                     Put_Line (F, To_String (Generator.Globals));
                     Put_Line (F, To_String (Generator.Output));
                     Close (F);
                     --  Put_Line ("PATH = " & Ada.Environment_Variables.Value ("PATH"));

                     Spawn
                       (Program_Name => "/opt/homebrew/bin/qbe",
                        Args         => QBE_Args,
                        Output_File  => "tmp/qbe.log",
                        Success      => Success,
                        Return_Code  => Status,
                        Err_To_Out   => True);

                     if Status /= 0 then
                        Put_Line ("QBE Compiling Failed: " & Status'Image);
                        Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
                        return;
                     end if;

                     Spawn
                       (Program_Name => "/usr/bin/cc",
                        Args         => CC_Args,
                        Output_File  => "tmp/cc.log",
                        Success      => Success,
                        Return_Code  => Status,
                        Err_To_Out   => True);

                     if Status /= 0 then
                        Put_Line ("CC Compiling Failed: " & Status'Image);
                        Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
                        return;
                     end if;
                  end;
               end;
            end;
         end;
      end;
   end;
end Nightshade;