public override bool Equals(SlangType other) { if (other is SlangPointerType) { return(true); } return(false); }
/// <summary> /// return custom type for pointer and custom types /// </summary> /// <param name="type">type</param> /// <returns>custom type (if exists), else null</returns> private SlangCustomType GetUserType(SlangType type) { SlangCustomType usedType = null; if (type is SlangCustomType t) { usedType = t; } else if (type is SlangPointerType pt) { usedType = pt.PtrType; } return(usedType); }
// helpers /// <summary> /// uses only for routines/fields declaration, another declares should use Visit() for types /// </summary> /// <param name="returnType"></param> /// <returns></returns> private string GetStringFromType(SlangType returnType) { var res = ""; var simpleTypes = new Dictionary <string, string> { { CompilerConstants.IntegerType, "int64_t" }, { CompilerConstants.RealType, "double" }, { CompilerConstants.CharacterType, "char" }, { CompilerConstants.BooleanType, "bool" }, { CompilerConstants.StringType, "std::string" } }; if (returnType is SlangSimpleType st) { res = simpleTypes[st.Name]; } else if (returnType is SlangArrayType at) { res += GetVectorTypeStart(at.Dimension); res += GetStringFromType(at.Type); res += GetVectorTypeEnd(at.Dimension); } else if (returnType is SlangCustomType ct) { var item = source.FindClass(ct); if (item.Header != null) { res = item.Header.Ident.Replace("\"", ""); } else { res = ct.ModuleName == moduleName ? ct.Name : $"{ct.ModuleName}::{ct.Name}"; } } else if (returnType is SlangPointerType pt) { res = $"std::shared_ptr<{GetStringFromType(pt.PtrType)}>"; } else if (returnType == null) { res = "void"; } return(res); }
public override bool Equals(SlangType other) { return(false); }
public abstract bool Equals(SlangType other);
public override bool Equals(SlangType other) => other is SlangSimpleType s && s.Name == Name;
public ExpressionResult(SlangType type, ExpressionValueType exprType) { Type = type; ExpressionType = exprType; }
public SlangCreateTypeExpression(SlangType type) { this.Type = type; }
/// <summary> /// Base type check, does not check LSP principle /// </summary> /// <param name="other">what type we check</param> /// <returns></returns> public override bool Equals(SlangType other) => (other is SlangCustomType t) && (t.Name == Name) && (t.ModuleName == ModuleName);
public override bool Equals(SlangType other) => other is SlangPointerType t && t.PtrType.Equals(PtrType);
public static void ThrowCannotInitializeAbstractClassException(SlangType type, FileInfo file, int line, int column) => ThrowException($"Cannot create variable or allocate memory for abstract class {type}", file, line, column);
public static void ThrowCannotAssignException(SlangType type, SlangType exprType, FileInfo file, int line, int column) => ThrowException($"Cannot assign value of type {exprType} to variable or constant with type {type}", file, line, column);
public static void ThrowInvalidUseOfTypeException(SlangType slangType, FileInfo file, int line, int column) => ThrowException($"Invalid use of type {slangType}", file, line, column);
public static void ThrowInvalidTypesForUnaryOperationException(ITerminalNode terminalNode, FileInfo file, SlangType type) => ThrowException($"Operation {terminalNode.GetText()} is not allowed for type {type}", file, terminalNode.Symbol);
public static void ThrowInvalidTypesForBinaryOperationException(IToken symbol, FileInfo file, SlangType leftType, SlangType rightType) => ThrowException($"Operation {symbol.Text} not allowed for types {leftType} and {rightType}", file, symbol);
private void ValidateContext(SLangGrammarParser.ThisHeaderContext thisHeader, ITerminalNode id, SLangGrammarParser.ImportHeadContext importHead, ITerminalNode accessModifier, ITerminalNode abstractToken, ITerminalNode overrideToken, SLangGrammarParser.RoutineArgListContext routineArgList, SLangGrammarParser.TypeNameContext typeName, SLangGrammarParser.StatementSeqContext statementSeq) { var isMethod = thisHeader != null; var symbol = id.Symbol; string nameOfThis = string.Empty; if (isMethod) { nameOfThis = thisHeader.Id().GetText(); ThrowIfReservedWord(nameOfThis, ModuleData.File, thisHeader.Id().Symbol); if (importHead != null) { ThrowImportHeaderMethodsException(ModuleData.File, id); } } var name = id.GetText(); ThrowIfReservedWord(name, ModuleData.File, symbol); var args = Visit(routineArgList) as List <RoutineArgNameTableItem>; ImportHeader header = null; if (importHead != null) { header = Visit(importHead) as ImportHeader; } SlangType returnType = typeName != null?Visit(typeName) as SlangType : null; var modifier = GetModifierByName(accessModifier.GetText()); var isAbstract = abstractToken != null; var isOverride = overrideToken != null; if (!isMethod && (isAbstract || isOverride)) { ThrowRoutinesAbstractOverrideException(ModuleData.File, abstractToken ?? overrideToken); } if (header != null && statementSeq.statement().Length != 0) { ThrowImportHeaderException(ModuleData.File, id); } if (isMethod) { if (Visit(thisHeader) is SlangCustomType methodTypeIdent && methodTypeIdent.ModuleName != ModuleData.Name) { ThrowModuleFromOtherClassModuleException(id, ModuleData.File); } if (isAbstract) { ThrowIfAbstractMethodPrivate(modifier, ModuleData.File, id); } if ((args ?? throw new InvalidOperationException(nameof(args))).Any(a => a.Name == nameOfThis)) { ThrowConfictsThisException(thisHeader.Id(), ModuleData.File); } var classData = Visit(thisHeader) as SlangCustomType; var foundClass = Table.FindClass(classData); if (foundClass.Methods.ContainsKey(name)) { ThrowMethodSignatureExistsException(classData, id, ModuleData.File); } if (isAbstract && statementSeq.statement().Length != 0) { ThrowAbstractEmptyException(id, ModuleData.File); } var method = new MethodNameTableItem { AccessModifier = modifier, Column = symbol.Column, Header = header, IsAbstract = isAbstract, IsOverride = isOverride, Line = symbol.Line, Name = name, NameOfThis = nameOfThis, Params = args, ReturnType = returnType }; if (modifier == AccessModifier.Public) { CheckLevelAccessForMethods(method, id, classData); } foundClass.CheckRoutineConflicts(moduleItem.ModuleData, method); foundClass.Methods.Add(method.Name, method); } else { if (moduleItem.Routines.ContainsKey(name)) { ThrowRoutineExistsException(id, ModuleData.File); } var routine = new RoutineNameTableItem { AccessModifier = modifier, Column = symbol.Column, Line = symbol.Line, Header = header, Name = name, Params = args, ReturnType = returnType }; if (modifier == AccessModifier.Public) { CheckLevelAccessForRoutines(routine, id, name); } moduleItem.CheckCommonNamesConflicts(routine.Name, routine.Line, routine.Column); moduleItem.Routines.Add(routine.Name, routine); } }