예제 #1
0
        public override void EnterVarDecl([NotNull] DaedalusParser.VarDeclContext context)
        {
            if (context.Parent.Parent is DaedalusParser.DaedalusFileContext || _assemblyBuilder.IsContextInsideExecBlock())
            {
                var typeName = context.typeReference().GetText();
                var type     = DatSymbolTypeFromString(typeName);
                if (type == DatSymbolType.Class)
                {
                    type = DatSymbolType.Instance;
                }

                for (int i = 0; i < context.ChildCount; i++)
                {
                    var varContext = context.GetChild(i);

                    if (varContext is TerminalNodeImpl)
                    {
                        continue; // skips ','
                    }
                    if (varContext is DaedalusParser.VarValueDeclContext varValueContext)
                    {
                        var name = varValueContext.nameNode().GetText();
                        if (_assemblyBuilder.IsContextInsideExecBlock())
                        {
                            // TODO consider making assemblyBuilder.active public and using it here
                            BaseExecBlockContext baseExecBlock = _assemblyBuilder.ExecBlocks.Last();
                            string execBlockName = baseExecBlock.GetSymbol().Name;
                            name = $"{execBlockName}.{name}";
                        }

                        var location = GetLocation(context);

                        int           parentIndex       = DatSymbol.NULL_INDEX;
                        string        parameterTypeName = context.typeReference().GetText();
                        DatSymbolType?parameterType     = DatSymbolTypeFromString(parameterTypeName);
                        if (parameterType is DatSymbolType.Class)
                        {
                            var parentSymbol = _assemblyBuilder.ResolveSymbol(parameterTypeName);
                            parentIndex = parentSymbol.Index;
                        }

                        var symbol = SymbolBuilder.BuildVariable(name, type, location, parentIndex); // TODO : Validate params
                        _assemblyBuilder.AddSymbol(symbol);
                    }

                    if (varContext is DaedalusParser.VarArrayDeclContext varArrayContext)
                    {
                        var name     = varArrayContext.nameNode().GetText();
                        var location = GetLocation(context);
                        var size     = EvaluatorHelper.EvaluteArraySize(varArrayContext.arraySize(), _assemblyBuilder);

                        var symbol =
                            SymbolBuilder.BuildArrOfVariables(name, type, (uint)size,
                                                              location); // TODO : Validate params
                        _assemblyBuilder.AddSymbol(symbol);
                    }
                }
            }
        }
예제 #2
0
        public override void EnterClassDef([NotNull] DaedalusParser.ClassDefContext context)
        {
            var className   = context.nameNode().GetText();
            var classSymbol = SymbolBuilder.BuildClass(className, 0, 0, GetLocation(context));

            _assemblyBuilder.AddSymbol(classSymbol);

            var  classId        = classSymbol.Index;
            int  classVarOffset = classSymbol.ClassOffset;
            uint classLength    = 0;

            // TODO: refactor later
            foreach (var varDeclContext in context.varDecl())
            {
                var typeName = varDeclContext.typeReference().GetText();
                var type     = DatSymbolTypeFromString(typeName);

                for (int i = 0; i < varDeclContext.ChildCount; i++)
                {
                    var varContext = varDeclContext.GetChild(i);

                    if (varContext is TerminalNodeImpl)
                    {
                        continue; // skips ','
                    }
                    if (varContext is DaedalusParser.VarValueDeclContext varValueContext)
                    {
                        var name     = varValueContext.nameNode().GetText();
                        var location = GetLocation(context);

                        var symbol = SymbolBuilder.BuildClassVar(name, type, 1, className, classId,
                                                                 classVarOffset, location); // TODO : Validate params
                        _assemblyBuilder.AddSymbol(symbol);

                        classVarOffset += (type == DatSymbolType.String ? 20 : 4);
                        classLength++;
                    }

                    if (varContext is DaedalusParser.VarArrayDeclContext varArrayContext)
                    {
                        var name     = varArrayContext.nameNode().GetText();
                        var location = GetLocation(context);
                        var size     = EvaluatorHelper.EvaluteArraySize(varArrayContext.arraySize(), _assemblyBuilder);

                        var symbol = SymbolBuilder.BuildClassVar(name, type, (uint)size, className, classId,
                                                                 classVarOffset, location); // TODO : Validate params
                        _assemblyBuilder.AddSymbol(symbol);

                        classVarOffset += (type == DatSymbolType.String ? 20 : 4) * size;
                        classLength++;
                    }
                }
            }

            classSymbol.ArrayLength = classLength;
            classSymbol.ClassSize   = classVarOffset - classSymbol.ClassOffset;
        }
예제 #3
0
 public override void EnterStringLiteralValue(DaedalusParser.StringLiteralValueContext context)
 {
     if (!_assemblyBuilder.IsInsideConstDef)
     {
         DatSymbolLocation location = GetLocation(context);
         string            value    = context.GetText().Replace("\"", "");
         DatSymbol         symbol   = SymbolBuilder.BuildStringConst(value, location);
         _assemblyBuilder.AddInstruction(new PushVar(symbol));
     }
 }
예제 #4
0
        public override void EnterParameterDecl(DaedalusParser.ParameterDeclContext context)
        {
            BaseExecBlockContext baseExecBlock = _assemblyBuilder.ExecBlocks.Last();
            string execBlockName      = baseExecBlock.GetSymbol().Name;
            string parameterLocalName = context.nameNode().GetText();
            string parameterName      = $"{execBlockName}.{parameterLocalName}";

            int parentIndex = DatSymbol.NULL_INDEX;

            string        parameterTypeName = context.typeReference().GetText();
            DatSymbolType?parameterType     = DatSymbolTypeFromString(parameterTypeName);

            if (parameterType is DatSymbolType.Class)
            {
                parameterType = DatSymbolType.Instance;
                var parentSymbol = _assemblyBuilder.ResolveSymbol(parameterTypeName);
                parentIndex = parentSymbol.Index;
            }

            DatSymbol symbol;
            var       location = GetLocation(context);

            var arraySizeContext = context.arraySize();

            if (arraySizeContext != null)
            {
                if (!uint.TryParse(arraySizeContext.GetText(), out var arrIndex))
                {
                    var constSymbol = _assemblyBuilder.ResolveSymbol(arraySizeContext.GetText());
                    if (constSymbol.Flags != DatSymbolFlag.Const || constSymbol.Type != DatSymbolType.Int)
                    {
                        throw new Exception($"Expected integer constant: {arraySizeContext.GetText()}");
                    }

                    arrIndex = (uint)(int)constSymbol.Content[0];
                }

                symbol = SymbolBuilder.BuildArrOfVariables(parameterName, parameterType.Value, arrIndex, location);
            }
            else
            {
                if (_assemblyBuilder.IsCurrentlyParsingExternals)
                {
                    symbol = SymbolBuilder.BuildExternalParameter(parameterName, parameterType.Value, location, parentIndex);
                }
                else
                {
                    symbol = SymbolBuilder.BuildParameter(parameterName, parameterType.Value, location, parentIndex);
                }
            }

            _assemblyBuilder.AddSymbol(symbol);
        }
예제 #5
0
        public override void EnterFunctionDef([NotNull] DaedalusParser.FunctionDefContext context)
        {
            string        funcName        = context.nameNode().GetText();
            string        returnTypeName  = context.typeReference().GetText();
            DatSymbolType returnType      = DatSymbolTypeFromString(returnTypeName);
            uint          parametersCount = (uint)context.parameterList().parameterDecl().Length;

            var symbol = SymbolBuilder.BuildFunc(funcName, parametersCount, returnType);

            _assemblyBuilder.AddSymbol(symbol);
            _assemblyBuilder.ExecBlockStart(symbol, ExecBlockType.Function);
        }
예제 #6
0
        public override void EnterPrototypeDef([NotNull] DaedalusParser.PrototypeDefContext context)
        {
            _assemblyBuilder.ErrorContext.Context = context.parentReference();

            var prototypeName     = context.nameNode().GetText();
            var referenceName     = context.parentReference().GetText();
            var refSymbol         = _assemblyBuilder.GetSymbolByName(referenceName);
            var referenceSymbolId = refSymbol.Index;
            var location          = GetLocation(context);

            var prototypeSymbol = SymbolBuilder.BuildPrototype(prototypeName, referenceSymbolId, location);

            _assemblyBuilder.AddSymbol(prototypeSymbol);

            _assemblyBuilder.ExecBlockStart(prototypeSymbol, ExecBlockType.Prototype);
        }
예제 #7
0
        public override void EnterInstanceDef(DaedalusParser.InstanceDefContext context)
        {
            _assemblyBuilder.ErrorContext.Context = context.parentReference();

            var instanceName      = context.nameNode().GetText();
            var referenceName     = context.parentReference().GetText();
            var refSymbol         = _assemblyBuilder.GetSymbolByName(referenceName);
            var referenceSymbolId = refSymbol.Index;
            var location          = GetLocation(context);

            var instanceSymbol = SymbolBuilder.BuildInstance(instanceName, referenceSymbolId, location);

            instanceSymbol.Flags |= DatSymbolFlag.Const;
            _assemblyBuilder.AddSymbol(instanceSymbol);

            _assemblyBuilder.ExecBlockStart(instanceSymbol, ExecBlockType.Instance);

            if (refSymbol.Type == DatSymbolType.Prototype)
            {
                _assemblyBuilder.AddInstruction(new Call(refSymbol));
            }
        }
예제 #8
0
        public override void EnterInstanceDecl(DaedalusParser.InstanceDeclContext context)
        {
            _assemblyBuilder.ErrorContext.Context = context.parentReference();

            var referenceName     = context.parentReference().GetText();
            var refSymbol         = _assemblyBuilder.GetSymbolByName(referenceName);
            var referenceSymbolId = refSymbol.Index;
            var location          = GetLocation(context);

            List <DatSymbol> symbols = new List <DatSymbol>();

            for (int i = 0; i < context.nameNode().Length; ++i)
            {
                string    instanceName   = context.nameNode()[i].GetText();
                DatSymbol instanceSymbol = SymbolBuilder.BuildInstance(instanceName, referenceSymbolId, location);
                _assemblyBuilder.AddSymbol(instanceSymbol);
                symbols.Add(instanceSymbol);
            }

            _assemblyBuilder.SharedBlockStart(symbols);
            _assemblyBuilder.AddInstruction(new Ret());
            _assemblyBuilder.ExecBlockEnd();
        }
예제 #9
0
        public override void EnterConstDef([NotNull] DaedalusParser.ConstDefContext context)
        {
            _assemblyBuilder.IsInsideConstDef = true;
            var typeName = context.typeReference().GetText();
            var type     = DatSymbolTypeFromString(typeName);

            if (type == DatSymbolType.Func)
            {
                type = DatSymbolType.Int;
            }

            for (int i = 0; i < context.ChildCount; i++)
            {
                var constContext = context.GetChild(i);

                if (constContext is TerminalNodeImpl)
                {
                    continue; // skips ','
                }
                if (constContext is DaedalusParser.ConstValueDefContext constValueContext)
                {
                    var name = constValueContext.nameNode().GetText();
                    if (_assemblyBuilder.IsContextInsideExecBlock())
                    {
                        BaseExecBlockContext baseExecBlock = _assemblyBuilder.ExecBlocks.Last();
                        string execBlockName = baseExecBlock.GetSymbol().Name;
                        name = $"{execBlockName}.{name}";
                    }

                    var location             = GetLocation(context);
                    var assignmentExpression = constValueContext.constValueAssignment().expressionBlock().expression();
                    var value = EvaluatorHelper.EvaluateConst(assignmentExpression, _assemblyBuilder, type);

                    var symbol = SymbolBuilder.BuildConst(name, type, value, location); // TODO : Validate params
                    _assemblyBuilder.AddSymbol(symbol);

                    continue;
                }

                if (constContext is DaedalusParser.ConstArrayDefContext constArrayContext)
                {
                    _assemblyBuilder.ErrorContext.Context = constArrayContext;

                    var name     = constArrayContext.nameNode().GetText();
                    var location = GetLocation(context);

                    int  declaredSize = 0;
                    bool compareDeclaredSizeAndElementsCount = true;

                    try
                    {
                        _assemblyBuilder.ErrorContext.Context = constArrayContext.arraySize();
                        declaredSize = EvaluatorHelper.EvaluteArraySize(constArrayContext.arraySize(), _assemblyBuilder);
                    }
                    catch (System.ArgumentNullException)
                    {
                        compareDeclaredSizeAndElementsCount = false;
                    }

                    if (declaredSize == 0 && compareDeclaredSizeAndElementsCount)
                    {
                        compareDeclaredSizeAndElementsCount = false;
                        _assemblyBuilder.Errors.Add(
                            new InvalidArraySizeError(
                                _assemblyBuilder.ErrorContext,
                                name,
                                declaredSize
                                )
                            );
                    }


                    var elements = constArrayContext.constArrayAssignment().expressionBlock()
                                   .Select(expr => EvaluatorHelper.EvaluateConst(expr.expression(), _assemblyBuilder, type))
                                   .ToArray();


                    if (compareDeclaredSizeAndElementsCount && declaredSize != elements.Length)
                    {
                        _assemblyBuilder.Errors.Add(
                            new InconsistentArraySizeError(
                                _assemblyBuilder.ErrorContext,
                                name,
                                declaredSize,
                                elements.Length
                                )
                            );
                    }

                    var symbol =
                        SymbolBuilder.BuildArrOfConst(name, type, elements, location); // TODO : Validate params
                    _assemblyBuilder.AddSymbol(symbol);
                }
            }
        }