Untitled

mail@pastecode.io avatar
unknown
csharp
a month ago
6.1 kB
0
Indexable
Never
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class NovelActionLanguageInterpreter
{
    public class ExternalValue
    {
        private Func<object>? valueGetter;
        private Action<dynamic>? valueSetter;
        public string key;

        public dynamic? Get()
        {
            return valueGetter?.Invoke();
        }

        public void Set(dynamic v)
        {
            valueSetter.Invoke(v);
        }

        public ExternalValue(string key, Func<double> numberGetter, Action<double> numberSetter)
        {
            this.key = key;
            this.valueGetter = () => numberGetter();
            this.valueSetter = (a) => numberSetter(a);
        }

        public ExternalValue(string key, Func<string> valueGetter, Action<string> valueSetter)
        {
            this.key = key;
            this.valueGetter = valueGetter;
            this.valueSetter = (a)=>valueSetter(a);
        }
    }



    public Dictionary<String, Func<List<dynamic>, dynamic>> functions = new Dictionary<string,  Func<List<dynamic>, dynamic>>();
    public Dictionary<String, dynamic> variables = new Dictionary<String, dynamic>();

    public void AddExternalFunction(string name, Func<List<dynamic>, dynamic> function)
    {
        functions.Add(name, function);
    }
    public dynamic GetVar(String name)
    {
        if (variables.ContainsKey(name))
        {
            return variables[name];
        }
        else
        {
            if (externalReferences.ContainsKey(name))
                return externalReferences[name].Get();
        }

        return null;
    }
    public void Interpret(String code)
    {
        var lines = code.Split(';');
        foreach (String line in lines)
        {
            if (IsStatement(line))
            {
                ExecuteStatement(line);
            }
            else
            {
                ExecuteExpression(line);
            }
        }
        
    }
    public bool IsStatement(String line)
    {
        if (line.Contains("=") || line.Contains("if ("))
        {
            return true;
        }

        return false;
    }
    public dynamic ExecuteExpression(string expression)
    {
        expression = expression.Trim();

        // Check if the expression is a constant
        if (double.TryParse(expression, out double constantValue))
        {
            // Expression is a numeric constant
            Console.WriteLine($"The expression is a constant: {constantValue}");
            return constantValue;
        }

        if (expression.Contains("'") && !expression.Contains('('))
        {
            return expression.Substring(1, expression.Length - 2);
        }
        if (expression.Contains("("))
        {
             //function call
             return CallExternalFunction(expression);
        }
        else
        {
            if (variables.ContainsKey(expression))
                return GetVar(expression);
            if (externalReferences.ContainsKey(expression))
                return GetCSharpValue(expression);
        }

        return null;
    }

    private Dictionary<string, ExternalValue> externalReferences = new Dictionary<string, ExternalValue>();
    public void BindCSharpValue(ExternalValue reference)
    {
        externalReferences[reference.key] = reference;
    }
    public dynamic GetCSharpValue(string name)
    {
        if (externalReferences.ContainsKey(name))
            return externalReferences[name].Get();
        return null;
    }

    public dynamic CallExternalFunction(string expression)
    {
        var parts = expression.Split("(");
        var functionName = parts[0];
        var functionArguments = parts[1].Substring(0, parts[1].Length - 1);
        var listOfArguments = functionArguments.Split(",").ToList().Select(x=>ExecuteExpression(x)).ToList();
        if (!functions.ContainsKey(functionName))
        {
            Debug.LogError("INTERPRETER ERROR:");
            Debug.LogError(functionName + " DOES NOT EXIST!!!! CANCELLING EXECUTION");
            return null;
        }
        return functions[functionName].Invoke(listOfArguments);
        return null;
    }
    
    public void ExecuteStatement(String statement)
    {
        //if is if
        if (statement.Contains("if ("))
        {
            var condition = statement.Replace("if (", "").Replace(")", "");
        }
        else
        {
            var parts = statement.Split("=");
            var variableName = parts[0].Trim();
            var expression = parts[1].Trim();
            dynamic expressionResult = ExecuteExpression(expression);
            if (variableName.Contains('+'))
            {
                variableName = variableName.Replace("+", "");
                if (externalReferences.ContainsKey(variableName))
                {
                    externalReferences[variableName].Set(GetCSharpValue(variableName)+expressionResult);
                }else{
                variables[variableName] += expressionResult;
                }
            }
            else if (expression.Contains("-"))
            {

                variableName = variableName.Replace("-", "");
                if (externalReferences.ContainsKey(variableName))
                {
                    externalReferences[variableName].Set(GetCSharpValue(variableName)-expressionResult);
                }
                else
                {
                    variables[variableName] -= expressionResult;
                }
            }
            else
            {
                if (externalReferences.ContainsKey(variableName))
                {
                    externalReferences[variableName].Set(expressionResult);
                }
                else
                {

                    variables[variableName] = expressionResult;
                }
            }
        }
    }
}
Leave a Comment