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); } } } }
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; }
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)); } }
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); }
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); }
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); }
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)); } }
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(); }
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); } } }