/// <summary> /// This will go over the cases and will evaluate the first clause whose match is equal the the expression. /// If no entry matches then undefined will be returned. /// </summary> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var expression = Expression.Eval(context, env, frame); if (expression.IsErrorValue) { return(expression); } foreach (var clause in Clauses) { if (clause.IsDefaultFallthrough) { return(clause.Expression.Eval(context, env, frame)); } else { var match = clause.Match.Eval(context, env, frame); if (match.IsErrorValue) { return(match); } if (expression.Equals(match)) { return(clause.Expression.Eval(context, env, frame)); } } } return(EvaluationResult.Undefined); }
/// <inheritdoc /> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var receiver = m_thisExpression.Eval(context, env, frame); if (receiver.IsErrorValue) { return(receiver); } if (receiver.IsUndefined) { context.Errors.ReportFailResolveSelectorDueToUndefined(env, m_thisExpression, Selector, Location); return(EvaluationResult.Error); } // Resolved expression can work only with module literal and with object literal. // It is impossible to get an instance of this type when a selector points to an ambient function. // To call an ambient in DScript v2, different ast node is used. if (receiver.Value is ModuleLiteral thisModule) { return(m_selector.Eval(context, thisModule, frame)); } if (receiver.Value is ObjectLiteral thisLiteral) { if (thisLiteral.TryProject(context, Selector, env, context.PredefinedTypes, out EvaluationResult projectionResult, Location)) { return(projectionResult); } context.Errors.ReportUnexpectedValueType( env, m_thisExpression, receiver, typeof(ObjectLiteral), typeof(ArrayLiteral)); return(EvaluationResult.Error); } // ThisExpression is not supported. context.Errors.ReportUnexpectedValueType( env, m_thisExpression, receiver, typeof(ModuleLiteral), typeof(ObjectLiteral)); return(EvaluationResult.Error); }
/// <inheritdoc/> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var result = m_expression.Eval(context, env, frame); if (result.IsErrorValue) { return(result); } if (!(result.Value is ModuleLiteral module)) { var thisNodeType = nameof(ModuleToObjectLiteral); throw Contract.AssertFailure( $"AstConverter should never create a '{thisNodeType}' node that wraps an expression that evaluates to something other than {nameof(ModuleLiteral)}. " + $"Instead, this '{thisNodeType}' wraps an expression of type '{m_expression.GetType().Name}' which evaluated to an instance of type '{result.Value?.GetType().Name}'."); } var bindings = module .GetAllBindings(context) .Where(kvp => kvp.Key != Constants.Names.RuntimeRootNamespaceAlias) .Select(kvp => { var name = SymbolAtom.Create(context.StringTable, kvp.Key); var location = kvp.Value.Location; var evalResult = module.GetOrEvalFieldBinding(context, name, kvp.Value, location); return(new Binding(name, evalResult.Value, location)); }) .ToArray(); if (bindings.Any(b => b.Body.IsErrorValue())) { return(EvaluationResult.Error); } var objectLiteral = ObjectLiteral.Create(bindings); return(EvaluationResult.Create(objectLiteral)); }
/// <inheritdoc /> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { // We ignore types, so no need to evaluate the type. return(Expression.Eval(context, env, frame)); }