Block
using CLanguage.Compiler;
using CLanguage.Interpreter;
using CLanguage.Types;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
namespace CLanguage.Syntax
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class Block : Statement
{
public VariableScope VariableScope { get; }
public List<Statement> Statements { get; } = new List<Statement>();
[System.Runtime.CompilerServices.Nullable(2)]
[field: System.Runtime.CompilerServices.Nullable(2)]
public Block Parent {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
[System.Runtime.CompilerServices.NullableContext(2)]
set;
}
public override bool AlwaysReturns => Statements.Any((Statement s) => s.AlwaysReturns);
public List<CompiledVariable> Variables { get; set; } = new List<CompiledVariable>();
public List<CompiledFunction> Functions { get; set; } = new List<CompiledFunction>();
public Dictionary<string, CType> Typedefs { get; set; } = new Dictionary<string, CType>();
public List<Statement> InitStatements { get; set; } = new List<Statement>();
public Dictionary<string, CStructType> Structures { get; set; } = new Dictionary<string, CStructType>();
public Dictionary<string, CEnumType> Enums { get; set; } = new Dictionary<string, CEnumType>();
public Block(VariableScope variableScope, IEnumerable<Statement> statements)
{
AddStatements(statements);
VariableScope = variableScope;
}
public Block(VariableScope variableScope)
{
VariableScope = variableScope;
}
public override string ToString()
{
if (InitStatements.Count > 0)
return "{[" + string.Join("; ", InitStatements) + "] " + string.Join("; ", Statements) + "}";
return "{" + string.Join("; ", Statements) + "}";
}
[System.Runtime.CompilerServices.NullableContext(2)]
public void AddStatement(Statement stmt)
{
if (stmt != null)
Statements.Add(stmt);
Block block = stmt as Block;
if (block != null)
block.Parent = this;
}
public void AddStatements(IEnumerable<Statement> stmts)
{
foreach (Statement stmt in stmts) {
AddStatement(stmt);
}
}
protected override void DoEmit(EmitContext ec)
{
ec.BeginBlock(this);
foreach (Statement statement in Statements) {
statement.Emit(ec);
}
ec.EndBlock();
}
public void AddVariable(string name, CType ctype)
{
Variables.Add(new CompiledVariable(name, 0, ctype));
}
public override void AddDeclarationToBlock(BlockContext context)
{
BlockContext context2 = new BlockContext(this, context);
foreach (Statement statement in Statements) {
statement.AddDeclarationToBlock(context2);
}
}
}
}