gen.adb (2580B)
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
package body Gen is
function Init (AST : Declaration_Vectors.Vector) return Generator is
begin
return
Generator'
(AST => AST, Globals => To_Unbounded_String (""), Output => To_Unbounded_String (""), Indent => 0);
end;
-----------------
-- gen unident --
-----------------
procedure Gen_Unindent (GG : in out Generator) is
begin
GG.Indent := GG.Indent - 4;
end;
---------------
-- gen ident --
---------------
procedure Gen_Indent (GG : in out Generator) is
begin
GG.Indent := GG.Indent + 4;
end;
----------------
-- put indent --
----------------
procedure Put_Indent (GG : in out Generator) is
begin
GG.Output := GG.Output & To_Unbounded_String (GG.Indent * ' ');
end;
--------------
-- gen call --
--------------
procedure Gen_Call (GG : in out Generator; Call : in Call_Expr) is
begin
declare
Param : constant Expr_Ref := Call.Params.Element (Call.Params.First_Index);
Content : Unbounded_String := Param.Lit_Str;
begin
-- if Call.Params.Length /= 1 then
-- raise Program_error with "cannot handle calls of more or less than 1 param yet";
-- end if;
GG.Globals := GG.GLobals & "data $str = { b " & (Content) & ", b 0 }" & ASCII.LF;
Put_Indent (GG);
GG.Output := GG.Output & "%r =w call $puts(l $str)" & ASCII.LF;
end;
end;
------------------
-- gen function --
------------------
procedure Gen_Function (GG : in out Generator; Func : in Func_Decl) is
begin
GG.Output := GG.Output & "export function w $" & Func.Name & "() {" & ASCII.LF;
GG.Output := GG.Output & "@start" & ASCII.LF;
Gen_Indent (GG);
for Stmt of Func.Stmts loop
if Stmt.Kind = Stmt_Call_Kind then
Gen_Call (GG, Stmt.Call);
end if;
end loop;
Put_Indent (GG);
GG.Output := GG.Output & "ret 0" & ASCII.LF;
Gen_Unindent (GG);
GG.Output := GG.Output & "}" & ASCII.LF;
end;
------------
-- gen IR --
------------
procedure Gen_IR (GG : in out Generator) is
begin
for Decl of GG.AST loop
if Decl.Kind = Function_Kind then
Gen_Function (GG, Decl.Func);
end if;
end loop;
Put_Line (To_String (GG.Globals));
Put_Line (To_String (GG.Output));
end;
end Gen;