private Tuple <OptFile, OptCache> GetOptModel(string name) { OptFile file; if (!this.optFiles.TryGetValue(name, out file)) { string fileName = AppSettings.WorkingDirectory + "FLIGHTMODELS\\" + name + ".opt"; if (!System.IO.File.Exists(fileName)) { return(null); } file = OptFile.FromFile(fileName); this.optFiles.Add(name, file); } OptCache cache; if (!this.optCaches.TryGetValue(name, out cache)) { cache = new OptCache(file); this.optCaches.Add(name, cache); } return(new Tuple <OptFile, OptCache>(file, cache)); }
/// <summary> /// Runs cast expression. /// [Syntax] (int)b /// </summary> private HybInstance RunCast(CastExpressionSyntax node) { var cache = OptCache.GetOrCreate(node, () => { return(new OptCastNode() { type = Resolver.GetType($"{node.Type}") }); }); var value = RunExpression(node.Expression); return(value.Cast(cache.type)); }
private HybInstance RunPrefixUnary(PrefixUnaryExpressionSyntax node) { var op = node.OperatorToken.Text; var operand = RunExpression(node.Operand); var cache = OptCache.GetOrCreate <PrefixUnaryExpressionSyntax, OptPrefixUnary>(node, () => { return(new OptPrefixUnary() { operandId = (node.Operand is IdentifierNameSyntax id) ? $"{id.Identifier}" : null, isPrimitiveIncOrDec = (op == "++" || op == "--") && node.Operand is IdentifierNameSyntax && operand.GetHybType().IsPrimitive });
private HybInstance ResolveLiteral(LiteralExpressionSyntax node) { var cache = OptCache.GetOrCreate(node, () => { var optNode = new OptLiteralNode(); if (node.Token.Value == null) { optNode.value = HybInstance.Null(); } else if (node.Token.Value is char c) { optNode.value = HybInstance.Char(c); } else if (node.Token.Value is string str) { optNode.value = HybInstance.String(str); } else if (node.Token.Value is bool b) { optNode.value = HybInstance.Bool(b); } else if (node.Token.Value is int i) { if (int.TryParse(node.Token.Text, out _) == false) { throw new SemanticViolationException($"Integer literal out of range"); } optNode.value = HybInstance.Int(i); } else if (node.Token.Value is float f) { optNode.value = HybInstance.Float(f); } else if (node.Token.Value is double d) { optNode.value = HybInstance.Double(d); } else { throw new InvalidOperationException(); } return(optNode); }); return(cache.value); }
private HybInstance RunMemberAccess(MemberAccessExpressionSyntax node) { var cache = OptCache.GetOrCreate <MemberAccessExpressionSyntax, OptRunMemberAccessNode>(node, () => { var result = new OptRunMemberAccessNode(); if (node.Expression is IdentifierNameSyntax idNode) { HybType type; var id = $"{idNode.Identifier}"; if (Resolver.TryGetType(id, out type)) { result.leftType = type; result.isStaticMemberAccess = true; } } return(result); }); if (cache.isStaticMemberAccess) { return(RunStaticMemberAccess(node, cache.leftType)); } var left = RunExpression(node.Expression); var right = node.Name.Identifier.Text; var accessLevel = AccessLevel.Outside; if (node.Expression is ThisExpressionSyntax || left.GetHybType() == Ctx.Method.DeclaringType) { // TODO: protected accessLevel = AccessLevel.This; } HybInstance o; if (left.GetPropertyOrField(right, out o, accessLevel)) { return(o); } throw new NoSuchMemberException(right); }
private void RunLocalDeclaration(LocalDeclarationStatementSyntax node) { var cache = OptCache.GetOrCreate(node, () => { var _typename = $"{node.Declaration.Type}"; var _isVar = _typename == "var"; return(new OptLocalDeclarationNode() { isVar = _isVar, type = _isVar ? null : Resolver.GetType(_typename) }); }); var isVar = cache.isVar; var type = cache.type; foreach (var v in node.Declaration.Variables) { var id = v.Identifier.ValueText; if (Vars.TryGetValue(id, out _)) { throw new SemanticViolationException($"Local variable redefination: {id}"); } if (isVar && v.Initializer == null) { throw new SemanticViolationException($"`var` should be initialized with declaration."); } HybInstance value = null; if (v.Initializer != null) { value = RunExpression(v.Initializer.Value); } else { value = type.GetDefault(); } Vars.SetValue(id, value); } }
/// <summary> /// Runs invocation expression. /// [Syntax] Console.WriteLine("Hello World"); /// Foo(1234); /// </summary> private HybInstance RunInvocation(InvocationExpressionSyntax node) { var cache = OptCache.GetOrCreate(node, () => { var optNode = new OptInvocationNode(); return(optNode); }); string calleeId = ""; string targetId = ""; HybInstance callee = null; SSMethodInfo[] callsite = null; HybType[] implicitGenericArgs = null; var(args, hasRefOrOut) = ResolveArgumentList(node.ArgumentList); if (node.Expression is MemberAccessExpressionSyntax ma) { var leftIsType = false; var rightName = $"{ma.Name.Identifier}"; implicitGenericArgs = ResolveGenericArgumentsFromName(ma.Name); if (ma.Expression is PredefinedTypeSyntax pd) { HybType leftType = null; leftIsType = true; leftType = Resolver.GetType($"{pd}"); callsite = leftType.GetStaticMethods(rightName); } else if (ma.Expression is IdentifierNameSyntax id) { HybType leftType = null; if (Resolver.TryGetType($"{id.Identifier}", out leftType)) { leftIsType = true; callsite = leftType.GetStaticMethods(rightName); } else { callee = ResolveId(id); callsite = callee.GetMethods(rightName); } calleeId = $"{id.Identifier}"; } else if (ma.Expression is ExpressionSyntax expr) { callee = RunExpression(expr); callsite = callee.GetMethods($"{ma.Name}"); } if (leftIsType == false && callsite.Length == 0) { callsite = ExtResolver.GetCallableExtensions(callee, $"{ma.Name}"); args = (new HybInstance[] { callee }).Concat(args).ToArray(); } targetId = $"{ma.Name}"; //callsite = ResolveMemberAccess(node.Expression as MemberAccessExpressionSyntax); } else if (node.Expression is SimpleNameSyntax || node.Expression is MemberBindingExpressionSyntax) { if (node.Expression is IdentifierNameSyntax ids) { HybInstance v; if (TryResolveId(ids.Identifier.Text, out v)) { implicitGenericArgs = ResolveGenericArgumentsFromName(ids); callee = v; callsite = v.GetMethods("Invoke"); } } if (callsite == null) { SimpleNameSyntax id = node.Expression as SimpleNameSyntax; if (id == null) { id = (node.Expression as MemberBindingExpressionSyntax)?.Name; callee = Ctx._bound; } else { callee = Ctx._this; } implicitGenericArgs = ResolveGenericArgumentsFromName(id); callsite = ResolveLocalMember(id) .Concat(Ctx.Method.DeclaringType.GetStaticMethods(id.Identifier.Text)) .ToArray(); targetId = id.Identifier.Text; } } if (callsite.Length == 0) { throw new NoSuchMethodException($"{calleeId}", targetId); } var method = OverloadingResolver.FindMethodWithArguments( Resolver, callsite, implicitGenericArgs.ToArray(), ref args); if (method == null) { throw new SemanticViolationException($"No matching override for `{targetId}`"); } if (callee != null && method.DeclaringType.Parent == callee.GetHybType()) { callee = callee.Parent; } var target = method.Target; if (target.IsCompiled && traps.ContainsKey(target.CompiledMethod)) { target = new Invokable(traps[target.CompiledMethod]); } var ret = target.Invoke(callee, args, hasRefOrOut); // post-invoke if (hasRefOrOut) { var count = 0; foreach (var arg in node.ArgumentList.Arguments) { if (arg.RefKindKeyword != null) { RunAssign(arg.Expression, args[count]); } count++; } } return(ret); }