IFPSTools.NET/LibIFPSCC/ABT/Statements.cs
zc e16c00799d ifpscc: initial commit
libifpscc: initial commit
readme: document ifpscc/libifpscc
license: add credits for ifpscc/libifpscc (derived from code also MIT licensed)
libifps: make additional fields/types public for libifpscc
libifps: fix field documentation for some opcodes
libifps: fix loading functions that are not exported
libifps: allow saving a nonexistant primitive type if the same primitive type was added already
libifps: fix parsing Extended constants
libifps: fix ushort/short being mapped to the wrong types in one table
csproj: set Prefer32Bit=false for release builds
2023-03-28 17:24:19 +01:00

371 lines
8.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace ABT {
//public enum StmtKind {
// GOTO,
// LABELED,
// CONT,
// BREAK,
// EXPR,
// COMPOUND,
// RETURN,
// WHILE,
// DO,
// FOR,
// SWITCH,
// CASE,
// DEFAULT,
// IF,
// IF_ELSE
//}
public abstract partial class Stmt {
public Env Env { get; }
public abstract void Accept(StmtVisitor visitor);
public virtual bool IsJump { get => false; }
}
/// <summary>
/// Goto Statement
/// </summary>
public sealed partial class GotoStmt : Stmt {
public GotoStmt(String label) {
this.Label = label;
}
public String Label { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => true;
}
/// <summary>
/// Labeled Statement
/// </summary>
public sealed partial class LabeledStmt : Stmt {
public LabeledStmt(String label, Stmt stmt) {
this.Label = label;
this.Stmt = stmt;
}
public String Label { get; }
public Stmt Stmt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => Stmt.IsJump;
}
/// <summary>
/// Continue Statement
/// </summary>
public sealed partial class ContStmt : Stmt {
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => true;
}
/// <summary>
/// Break Statement
/// </summary>
public sealed partial class BreakStmt : Stmt {
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => true;
}
/// <summary>
/// Expression Statement
/// </summary>
public sealed partial class ExprStmt : Stmt {
public ExprStmt(Option<Expr> exprOpt) {
this.ExprOpt = exprOpt;
}
public Option<Expr> ExprOpt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => false;
}
public sealed partial class CompoundStmt : Stmt {
public CompoundStmt(List<Tuple<Env, Decln>> declns, List<Tuple<Env, Stmt>> stmts) {
this.Declns = declns;
this.Stmts = stmts;
}
public List<Tuple<Env, Decln>> Declns { get; }
public List<Tuple<Env, Stmt>> Stmts { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => Declns.Count == 0 && Stmts.Count >= 1 && Stmts.First().Item2.IsJump;
}
public sealed partial class ReturnStmt : Stmt {
public ReturnStmt(Option<Expr> exprOpt) {
this.ExprOpt = exprOpt;
}
public Option<Expr> ExprOpt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
}
/// <summary>
/// While Statement
///
/// while (Cond) {
/// Body
/// }
///
/// Cond must be of scalar Type
/// </summary>
// +--> start: continue:
// | test Cond
// | jz finish --+
// | Body |
// +------- jmp start |
// finish: <-------+
//
public sealed partial class WhileStmt : Stmt {
public WhileStmt(Expr cond, Stmt body) {
if (!cond.Type.IsScalar) {
throw new InvalidProgramException().Attach(cond);
}
this.Cond = cond;
this.Body = body;
}
public Expr Cond { get; }
public Stmt Body { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
}
/// <summary>
/// Do-while Stmt
///
/// do {
/// Body
/// } while (Cond);
///
/// Cond must be of scalar Type
/// </summary>
// +--> start:
// | Body
// | continue:
// | test Cond
// +------- jnz start
// finish:
public sealed partial class DoWhileStmt : Stmt {
public DoWhileStmt(Stmt body, Expr cond) {
this.Body = body;
this.Cond = cond;
}
public Stmt Body { get; }
public Expr Cond { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => Body.IsJump;
}
/// <summary>
/// for (Init; Cond; Loop) {
/// Body
/// }
///
/// Cond must be scalar
/// </summary>
//
// Init
// +--> start:
// | test Cond
// | jz finish --+
// | Body |
// | continue: |
// | Loop |
// +------- jmp start |
// finish: <-------+
//
public sealed partial class ForStmt : Stmt {
public ForStmt(Option<Expr> init, Option<Expr> cond, Option<Expr> loop, Stmt body) {
this.Init = init;
this.Cond = cond;
this.Loop = loop;
this.Body = body;
}
public Option<Expr> Init { get; }
public Option<Expr> Cond { get; }
public Option<Expr> Loop { get; }
public Stmt Body { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
}
/// <summary>
/// Switch Statement
/// </summary>
//
// cmp Cond, value1
// je case1
// cmp Cond, value2
// je case2
// ...
// cmp Cond, value_n
// je case_n
// jmp default # if no default, then default = finish
//
// case1:
// stmt
// case2:
// stmt
// ...
// case_n:
// stmt
// finish:
public sealed partial class SwitchStmt : Stmt {
public SwitchStmt(Expr expr, Stmt stmt) {
this.Expr = expr;
this.Stmt = stmt;
}
public Expr Expr { get; }
public Stmt Stmt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
}
/// <summary>
/// Case Statement
/// </summary>
public sealed partial class CaseStmt : Stmt {
public CaseStmt(Int32 value, Stmt stmt) {
this.Value = value;
this.Stmt = stmt;
}
public Int32 Value { get; }
public Stmt Stmt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => Stmt.IsJump;
}
public sealed partial class DefaultStmt : Stmt {
public DefaultStmt(Stmt stmt) {
this.Stmt = stmt;
}
public Stmt Stmt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
public override bool IsJump => Stmt.IsJump;
}
/// <summary>
/// If Statement: if (Cond) stmt;
/// If Cond is non-zero, stmt is executed.
///
/// Cond must be arithmetic or pointer Type.
/// </summary>
// test Cond
// +------- jz finish
// | Body
// +--> finish:
public sealed partial class IfStmt : Stmt {
public IfStmt(Expr cond, Stmt stmt) {
this.Cond = cond;
this.Stmt = stmt;
}
public Expr Cond { get; }
public Stmt Stmt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
}
/// <summary>
/// If-else Statement
/// if (Cond) {
/// true_stmt
/// } else {
/// false_stmt
/// }
/// </summary>
///
// test Cond
// +------- jz false
// | true_stmt
// | jmp finish --+
// +--> false: |
// false_stmt |
// finish: <--------+
//
public sealed partial class IfElseStmt : Stmt {
public IfElseStmt(Expr cond, Stmt trueStmt, Stmt falseStmt) {
this.Cond = cond;
this.TrueStmt = trueStmt;
this.FalseStmt = falseStmt;
}
public Expr Cond { get; }
public Stmt TrueStmt { get; }
public Stmt FalseStmt { get; }
public override void Accept(StmtVisitor visitor) {
visitor.Visit(this);
}
}
}