Example #1
0
        public virtual void CheckArgumentsOverload(IList <Function> @group, DFSM stateMachine)
        {
            var typeCheckStates = stateMachine.Q.Except(stateMachine.F).ToList();
            var finalStates     = stateMachine.F;

            // Create a set of unique parameter types.
            var uniqueTypes = @group.SelectMany(method => method.Parameters)
                              .Select(p => p.Type).Distinct().ToList();

            // Type check states.
            for (var i = 0; i < typeCheckStates.Count; i++)
            {
                NewLineIfNeeded();

                if (i > 0)
                {
                    Unindent();
                    WriteLine($"typecheck{i}:");
                    Indent();
                }

                var state       = typeCheckStates[i];
                var transitions = stateMachine.Delta.Where(t => t.StartState == state).ToArray();

                foreach (var transition in transitions)
                {
                    NewLineIfNeeded();

                    var isInitialState = stateMachine.Q0.Contains(state);
                    var paramIndex     = isInitialState ? 0 :
                                         int.Parse(transition.StartState.Split(' ').Last().Split('_').Last()) + 1;

                    var type = uniqueTypes[(int)transition.Symbol];

                    var condition = GenerateTypeCheckForParameter(paramIndex, type);

                    WriteLine($"if ({condition})");

                    var nextState = typeCheckStates.Contains(transition.EndState)
                        ? $"typecheck{typeCheckStates.FindIndex(s => s == transition.EndState)}"
                        : $"overload{finalStates.FindIndex(s => s == transition.EndState)}";
                    WriteLineIndent($"goto {nextState};");
                    NewLine();
                }

                WriteLine("goto error;");
                NeedNewLine();

                NeedNewLine();
            }
            NewLineIfNeeded();
        }
Example #2
0
        public virtual void GenerateOverloadCalls(IList <Function> @group, DFSM stateMachine)
        {
            // Final states.
            for (var i = 0; i < stateMachine.F.Count; i++)
            {
                NewLineIfNeeded();

                var function = @group[i];
                WriteLine($"// {function.Signature}");

                Unindent();
                WriteLine($"overload{i}:");
                Indent();

                WriteOpenBraceAndIndent();
                {
                    GenerateFunctionCall(function);
                }
                UnindentAndWriteCloseBrace();
                NeedNewLine();
            }
        }
Example #3
0
        private void CheckArgumentsOverload(IList <Function> @group, DFSM stateMachine)
        {
            var typeCheckStates = stateMachine.Q.Except(stateMachine.F).ToList();
            var finalStates     = stateMachine.F;

            // Create a set of unique parameter types.
            var uniqueTypes = @group.SelectMany(method => method.Parameters)
                              .Select(p => p.Type).Distinct().ToList();

            // Type check states.
            for (var i = 0; i < typeCheckStates.Count; i++)
            {
                NewLineIfNeeded();

                if (i > 0)
                {
                    Unindent();
                    WriteLine($"typecheck{i}:");
                    Indent();
                }

                var state       = typeCheckStates[i];
                var transitions = stateMachine.Delta.Where(t => t.StartState == state).ToArray();

                foreach (var transition in transitions)
                {
                    NewLineIfNeeded();

                    var isInitialState = stateMachine.Q0.Contains(state);
                    var paramIndex     = isInitialState ? 0 :
                                         int.Parse(transition.StartState.Split(' ').Last().Split('_').Last()) + 1;

                    var type = uniqueTypes[(int)transition.Symbol];

                    var typeChecker = new NAPITypeCheckGen(paramIndex);
                    type.Visit(typeChecker);

                    var condition = typeChecker.Generate();
                    if (string.IsNullOrWhiteSpace(condition))
                    {
                        throw new NotSupportedException();
                    }

                    WriteLine($"if ({condition})");

                    var nextState = typeCheckStates.Contains(transition.EndState)
                        ? $"typecheck{typeCheckStates.FindIndex(s => s == transition.EndState)}"
                        : $"overload{finalStates.FindIndex(s => s == transition.EndState)}";
                    WriteLineIndent($"goto {nextState};");
                    NewLine();
                }

                WriteLine("goto error;");
                NeedNewLine();

                NeedNewLine();
            }
            NewLineIfNeeded();

            // Error state.
            Unindent();
            WriteLine($"error:");
            Indent();

            WriteLine("status = napi_throw_type_error(env, nullptr, \"Unsupported argument type\");");
            WriteLine("assert(status == napi_ok);");
            NewLine();

            WriteLine("return nullptr;");
            NewLine();
        }
Example #4
0
        public virtual void CheckArgumentsOverload(List <Function> @group, DFSM stateMachine)
        {
            int GetParamIndex(Transition transition, string state)
            {
                var isInitialState = stateMachine.Q0.Contains(state);
                var paramIndex     = isInitialState ? 0 : int.Parse(transition.StartState.Split(' ').Last().Split('_').Last()) + 1;

                return(paramIndex);
            }

            var typeCheckStates = stateMachine.Q.Except(stateMachine.F).ToList();
            var finalStates     = stateMachine.F;

            // Create a set of unique parameter types.
            var uniqueTypes = @group.SelectMany(method => method.Parameters)
                              .Select(p => p.Type).Distinct().ToList();

            // Type check states.
            for (var i = 0; i < typeCheckStates.Count; i++)
            {
                NewLineIfNeeded();

                if (i > 0)
                {
                    Unindent();
                    WriteLine($"typecheck{i}:");
                    Indent();
                }

                var state       = typeCheckStates[i];
                var transitions = stateMachine.Delta.Where(t => t.StartState == state).ToArray();

                // Deal with default parameters.
                var currentParamIndex = GetParamIndex(transitions.First(), state);
                var defaultParams     = @group.Where(f => f.Parameters.Count > currentParamIndex)
                                        .Select(f => f.Parameters[currentParamIndex])
                                        .Where(p => p.HasDefaultValue).ToArray();

                // Check for an ambiguous case of overload resolution and throw. This does prevents some technically
                // legal overloads from being generated, so in the future this can be updated to just throw
                // a runtime error in JS instead, which would allow the ambiguous overloads to be called when
                // resolved with all explicit arguments.
                if (defaultParams.Length > 1)
                {
                    throw new Exception($"Found ambiguity between default parameter overloads for: " +
                                        $"{@group.First().QualifiedOriginalName}");
                }

                if (defaultParams.Length == 1)
                {
                    WriteLine($"if (argc == {currentParamIndex})");

                    var overload = defaultParams.First().Namespace as Function;
                    var index    = @group.FindIndex(f => f == overload);
                    WriteLineIndent($"goto overload{index};");
                    NewLine();
                }

                foreach (var transition in transitions)
                {
                    NewLineIfNeeded();

                    var paramIndex = GetParamIndex(transition, state);
                    var type       = uniqueTypes[transition.Symbol];
                    var condition  = GenerateTypeCheckForParameter(paramIndex, type);

                    WriteLine($"if ({condition})");

                    var nextState = typeCheckStates.Contains(transition.EndState)
                        ? $"typecheck{typeCheckStates.FindIndex(s => s == transition.EndState)}"
                        : $"overload{finalStates.FindIndex(s => s == transition.EndState)}";
                    WriteLineIndent($"goto {nextState};");
                    NewLine();
                }

                WriteLine("goto error;");
                NeedNewLine();

                NeedNewLine();
            }
            NewLineIfNeeded();
        }