SharpC: A C Interpreter In C# - 1101

Keywords: C#

If you run the following test C code contained in multiple recursive calls:

...
void fork2(int a, int b)
{
    if ((a + b) % 1024 == 0)
        print("iterate fork2: a=%i, b=%i\n", a, b);
    
    if (a + b == 2)
        return;
    else
        fork2(--a, --b);
}

...

void main()
{
    ...
    fork2(65535, 65535);
    ...
}

Will cause a StackOverflowException error. This is because the default stack size is 1M and will be exhausted soon.
terms of settlement:

  1. Use loops instead of recursion.
  2. Use a smaller number of recursions.
  3. Modify SharpC to be competent.

Obviously, 1 and 2 are not considered.
You can make the following changes to SharpC:
First, set a large stack size. In SharpC:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;

namespace SharpC
{
    using Grammar;

    public class SharpC
    {
        // Static
        static public int MaxStackSize = 1024 * 1024 * 512;  //Open a 512M stack
        ...

Because the program's stack cannot be set, only one more thread can be opened:

namespace SharpC
{
    using Grammar;

    public class SharpC
    {

        ....
public void Run(bool forceReparsing = false)
        {
            if (!m_lastParsingResult || forceReparsing)
                Parse();

            if (m_context != null)
            {
                if (OnBeforeRun != null)
                    OnBeforeRun(this, m_context);

                (new System.Threading.Thread(delegate() {
                        
                        try
                        {
                            IsRunning = true;
                            m_context.Run(m_context);
                        }
                        finally
                        {
                            IsRunning = false;

                            if (OnAfterRun != null)
                                OnAfterRun(this, m_context);
                        }
                }, MaxStackSize)).Start();
            }
        }

        ....

In addition, the method of saving and restoring parameters in functiondefinition.cs is wrong. The correct way is to comment them out!

namespace SharpC.Grammar.Function
{
    public class FunctionDefine : Context
    {
        ...
        private void BeforeRun(Context ctx, List<Expression.Operand.Operand> parameters)
        {
            if (IsFirstRunning)
            {
                ConfigReturnEvent(ctx);

                AllocateFixedArguments(ctx);
                
                IsFirstRunning = false;
            }

            if (IsVariableArgument)
            {
                FreeVariableArgument(ctx);

                AllocateVariableArguments(ctx, parameters);
            }

            //SavePreviousParameters(ctx);

            InitArguments(ctx, parameters);

            IteratorCount++;
        }
        ....

private void AfterRun(Context ctx)
        {
            IteratorCount--;

            if (IteratorCount > 0)
            {
                /*
                if (m_parameterStack.Count > 0)
                {
                    RestoreParameter(ctx);
                }
                */
            }
            else
            {
                // Clean variable arguments
                if (IsVariableArgument)
                {
                    FreeVariableArgument(ctx);
                }
            }
        }

       ...

Now you can do deep recursion.
Continue to run the test code, recurse 65535 times, and output the result of recursion every 512 times. The operation results are as follows:
Operation result:

Posted by lynxus on Tue, 15 Oct 2019 07:55:33 -0700