public AssemblyBuilder(bool verbose = true)
        {
            ExecBlocks          = new List <BaseExecBlockContext>();
            Symbols             = new List <DatSymbol>();
            _symbolsDict        = new Dictionary <string, DatSymbol>();
            _activeContext      = null;
            ActiveExecBlock     = null;
            _assignmentLeftSide = new List <SymbolInstruction>();
            FuncCallCtx         = null;


            _nextStringSymbolNumber     = 10000;
            IsInsideConstDef            = false;
            IsCurrentlyParsingExternals = false;

            IsInsideArgList         = false;
            IsInsideAssignment      = false;
            IsInsideReturnStatement = false;
            AssignmentType          = DatSymbolType.Undefined;
            _nextSymbolIndex        = 0;
            _verbose = verbose;

            Errors       = new List <CompilationMessage>();
            ErrorContext = new ErrorContext(this);
        }
        public void FuncCallStart(string funcName)
        {
            DatSymbol symbol = GetSymbolByName(funcName);

            List <DatSymbolType> parametersTypes = new List <DatSymbolType>();

            for (int i = 1; i <= symbol.ParametersCount; ++i)
            {
                DatSymbol parameter = Symbols[symbol.Index + i];
                parametersTypes.Add(parameter.Type);
            }

            AssemblyInstruction instruction;

            if (symbol.Flags.HasFlag(DatSymbolFlag.External))
            {
                instruction = new CallExternal(symbol);
            }
            else
            {
                instruction = new Call(symbol);
            }

            FuncCallCtx    = new FuncCallContext(_activeContext, FuncCallCtx, parametersTypes, symbol);
            _activeContext = FuncCallCtx;
            _activeContext.SetEndInstruction(instruction);

            IsInsideArgList = true;
        }
 public FuncCallContext(FuncCallContext ctx) : base(ctx.Parent)
 {
     _symbol          = ctx._symbol;
     _parametersTypes = ctx._parametersTypes;
     ArgIndex         = ctx.ArgIndex;
     OuterCall        = ctx.OuterCall;
     _instructions    = ctx._instructions;
 }
 public FuncCallContext(AssemblyBuilderContext parent, FuncCallContext outerCall, List <DatSymbolType> parametersTypes, DatSymbol symbol) : base(parent)
 {
     _symbol          = symbol;
     _parametersTypes = parametersTypes;
     ArgIndex         = -1;
     OuterCall        = outerCall;
     _instructions    = new List <AssemblyElement>();
 }
 public AssemblyBuilderSnapshot(AssemblyBuilder assemblyBuilder)
 {
     ActiveExecBlock         = assemblyBuilder.ActiveExecBlock;
     IsInsideArgList         = assemblyBuilder.IsInsideArgList;
     IsInsideAssignment      = assemblyBuilder.IsInsideAssignment;
     IsInsideIfCondition     = assemblyBuilder.IsInsideIfCondition;
     IsInsideReturnStatement = assemblyBuilder.IsInsideReturnStatement;
     AssignmentType          = assemblyBuilder.AssignmentType;
     FuncCallCtx             = assemblyBuilder.FuncCallCtx == null ? null : new FuncCallContext(assemblyBuilder.FuncCallCtx);
 }
        public void LoadStateFromSnapshot(AssemblyBuilderSnapshot snapshot)
        {
            ActiveExecBlock = snapshot.ActiveExecBlock;

            IsInsideArgList         = snapshot.IsInsideArgList;
            IsInsideAssignment      = snapshot.IsInsideAssignment;
            IsInsideIfCondition     = snapshot.IsInsideIfCondition;
            IsInsideReturnStatement = snapshot.IsInsideReturnStatement;
            AssignmentType          = snapshot.AssignmentType;
            FuncCallCtx             = snapshot.FuncCallCtx;
        }
        public void FuncCallEnd()
        {
            List <AssemblyElement> instructions = _activeContext.GetInstructions();

            FuncCallCtx    = FuncCallCtx.OuterCall;
            _activeContext = _activeContext.Parent;
            AddInstructions(instructions);

            if (FuncCallCtx == null)
            {
                IsInsideArgList = false;
            }
        }