Reworked function handling, support for type checking internal CSharp functions
This commit is contained in:
parent
81a6b05b26
commit
f08d1c2541
|
@ -24,6 +24,11 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
private readonly bool _passScriptReference;
|
private readonly bool _passScriptReference;
|
||||||
public System.Type ReturnType { get; }
|
public System.Type ReturnType { get; }
|
||||||
|
|
||||||
|
public IEnumerable<System.Type> GetParameterTypes()
|
||||||
|
{
|
||||||
|
return _method.GetMethods().First().Parameters.Select(x => x.Type);
|
||||||
|
}
|
||||||
|
|
||||||
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script)
|
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script)
|
||||||
{
|
{
|
||||||
var types = _directTypeManipulation
|
var types = _directTypeManipulation
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using Upsilon.BaseTypes.Number;
|
using Upsilon.BaseTypes.Number;
|
||||||
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes
|
namespace Upsilon.BaseTypes
|
||||||
{
|
{
|
||||||
public enum Type
|
[Flags]
|
||||||
|
public enum Type : byte
|
||||||
{
|
{
|
||||||
Unknown,
|
Unknown = 0,
|
||||||
Nil,
|
Nil = 1,
|
||||||
Boolean,
|
Boolean = 2,
|
||||||
Number,
|
Number = 4,
|
||||||
String,
|
String = 8,
|
||||||
Function,
|
Function = 16,
|
||||||
UserData,
|
UserData = 32,
|
||||||
Thread,
|
Thread = 64,
|
||||||
Table,
|
Table = 128,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
public class UserDataMethod
|
public class UserDataMethod
|
||||||
{
|
{
|
||||||
private class UserDataMethodPart
|
public class UserDataMethodPart
|
||||||
{
|
{
|
||||||
public UserDataMethodPart(MethodInfo method)
|
public UserDataMethodPart(MethodInfo method)
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
public UserDataMethodParameter[] Parameters { get; }
|
public UserDataMethodParameter[] Parameters { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct UserDataMethodParameter
|
public struct UserDataMethodParameter
|
||||||
{
|
{
|
||||||
public UserDataMethodParameter(ParameterInfo info)
|
public UserDataMethodParameter(ParameterInfo info)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,11 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
MethodParts.Add(part);
|
MethodParts.Add(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<UserDataMethodPart> GetMethods()
|
||||||
|
{
|
||||||
|
return MethodParts;
|
||||||
|
}
|
||||||
|
|
||||||
public MethodInfo GetMethod(System.Type[] parameterTypes)
|
public MethodInfo GetMethod(System.Type[] parameterTypes)
|
||||||
{
|
{
|
||||||
foreach (var userDataMethodPart in MethodParts)
|
foreach (var userDataMethodPart in MethodParts)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
using Upsilon.BaseTypes.Number;
|
using Upsilon.BaseTypes.Number;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.BoundTypes;
|
using Upsilon.BoundTypes;
|
||||||
using Upsilon.Parser;
|
using Upsilon.Parser;
|
||||||
using Type = Upsilon.BaseTypes.Type;
|
using Type = Upsilon.BaseTypes.Type;
|
||||||
|
@ -55,7 +56,7 @@ namespace Upsilon.Binder
|
||||||
var resultType = Scope.ReturnType;
|
var resultType = Scope.ReturnType;
|
||||||
Scope = Scope.ParentScope;
|
Scope = Scope.ParentScope;
|
||||||
var variable =
|
var variable =
|
||||||
(FunctionVariableSymbol) unboundFunctionStatement.Value.Scope.ParentScope.Variables[
|
(ScriptFunctionVariableSymbol) unboundFunctionStatement.Value.Scope.ParentScope.Variables[
|
||||||
unboundFunctionStatement.Key];
|
unboundFunctionStatement.Key];
|
||||||
variable.IsBound = true;
|
variable.IsBound = true;
|
||||||
variable.ResultType = resultType;
|
variable.ResultType = resultType;
|
||||||
|
@ -209,59 +210,39 @@ namespace Upsilon.Binder
|
||||||
var returnType = Type.Unknown;
|
var returnType = Type.Unknown;
|
||||||
if (ResolveVariable(expression) is FunctionVariableSymbol function)
|
if (ResolveVariable(expression) is FunctionVariableSymbol function)
|
||||||
{
|
{
|
||||||
if (!function.IsBound)
|
if (function is ScriptFunctionVariableSymbol scriptFunction)
|
||||||
|
{
|
||||||
|
if (!scriptFunction.IsBound)
|
||||||
{
|
{
|
||||||
Scope = new BoundScope(Scope);
|
Scope = new BoundScope(Scope);
|
||||||
for (var index = 0; index < function.Parameters.Length; index++)
|
for (var index = 0; index < scriptFunction.Parameters.Length; index++)
|
||||||
{
|
{
|
||||||
var functionVariable = function.Parameters[index];
|
var functionVariable = scriptFunction.Parameters[index];
|
||||||
var callingVariable = parameters[index];
|
var callingVariable = parameters[index];
|
||||||
functionVariable.Type = callingVariable.Type;
|
functionVariable.Type = callingVariable.Type;
|
||||||
Scope.DefineLocalVariable(functionVariable);
|
Scope.DefineLocalVariable(functionVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
var unboundFunctionStatement = _unboundFunctions[function.Name];
|
var unboundFunctionStatement = _unboundFunctions[scriptFunction.Name];
|
||||||
unboundFunctionStatement.Block =
|
unboundFunctionStatement.Block =
|
||||||
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock);
|
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.UnboundBlock);
|
||||||
returnType = Scope.ReturnType;
|
returnType = Scope.ReturnType;
|
||||||
Scope = Scope.ParentScope;
|
Scope = Scope.ParentScope;
|
||||||
function.IsBound = true;
|
scriptFunction.IsBound = true;
|
||||||
function.ResultType = returnType;
|
scriptFunction.ResultType = returnType;
|
||||||
_unboundFunctions.Remove(function.Name);
|
_unboundFunctions.Remove(scriptFunction.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
returnType = function.ResultType;
|
returnType = function.ResultType;
|
||||||
|
|
||||||
var pars = function.Parameters;
|
var (isValid, error, wrongParameter) = function.ValidateParameters(parameters.ToImmutable());
|
||||||
|
if (!isValid)
|
||||||
|
|
||||||
if (!function.IsInternal)
|
|
||||||
{
|
{
|
||||||
if (pars.Length != parameters.Count)
|
var span = e.Span;
|
||||||
{
|
if (wrongParameter != null)
|
||||||
_diagnostics.LogError(
|
span = wrongParameter.Span;
|
||||||
$"Invalid number of parameters for function '{function.Name}'. Expected {pars.Length}, got {parameters.Count}",
|
_diagnostics.LogError(error, span);
|
||||||
e.Span);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (var i = 0; i < pars.Length; i++)
|
|
||||||
{
|
|
||||||
var functionParameter = pars[i];
|
|
||||||
var callingParameter = parameters[i];
|
|
||||||
if (functionParameter.Type != Type.Unknown &&
|
|
||||||
callingParameter.Type != Type.Unknown && callingParameter.Type != Type.Nil)
|
|
||||||
{
|
|
||||||
if (callingParameter.Type != functionParameter.Type)
|
|
||||||
{
|
|
||||||
_diagnostics.LogError(
|
|
||||||
$"Invalid type for function '{function.Name}' at parameter '{functionParameter.Name}'. " +
|
|
||||||
$"Expected type '{functionParameter.Type}', got '{callingParameter.Type}'",
|
|
||||||
callingParameter.Span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType);
|
return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType);
|
||||||
|
@ -532,7 +513,7 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
if (!Scope.TryGetVariable(name, !isLocal, out var variable))
|
if (!Scope.TryGetVariable(name, !isLocal, out var variable))
|
||||||
{
|
{
|
||||||
var functionVariable = new FunctionVariableSymbol(name, isLocal, parameters.ToImmutable(), func.ReturnType, false)
|
var functionVariable = new ScriptFunctionVariableSymbol(name, isLocal, parameters.ToImmutable(), func.ReturnType)
|
||||||
{
|
{
|
||||||
CommentValue = commentData.ToArray()
|
CommentValue = commentData.ToArray()
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Type = Upsilon.BaseTypes.Type;
|
using Type = Upsilon.BaseTypes.Type;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using Upsilon.BaseTypes;
|
|
||||||
using Upsilon.BoundTypes;
|
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
|
||||||
{
|
|
||||||
public class VariableSymbol
|
|
||||||
{
|
|
||||||
public VariableSymbol(string name, Type type, bool local)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
Local = local;
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Type Type { get; set; }
|
|
||||||
public bool Local { get; }
|
|
||||||
public string Name { get; }
|
|
||||||
public string[] CommentValue { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FunctionVariableSymbol : VariableSymbol
|
|
||||||
{
|
|
||||||
public ImmutableArray<VariableSymbol> Parameters { get; }
|
|
||||||
public Type ResultType { get; internal set; }
|
|
||||||
public bool IsBound { get; set; }
|
|
||||||
public bool IsInternal { get; }
|
|
||||||
|
|
||||||
public FunctionVariableSymbol(string name, bool local, ImmutableArray<VariableSymbol> parameters, Type resultType, bool isInternal)
|
|
||||||
: base(name, Type.Function, local)
|
|
||||||
{
|
|
||||||
Parameters = parameters;
|
|
||||||
ResultType = resultType;
|
|
||||||
IsInternal = isInternal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FunctionParameterSymbol : VariableSymbol
|
|
||||||
{
|
|
||||||
public BoundTypeDefinition BoundTypeDefinition { get; }
|
|
||||||
|
|
||||||
public FunctionParameterSymbol(string name, Type type) : base(name, type, true)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public FunctionParameterSymbol(string name, BoundTypeDefinition type) : base(name, type.ScriptType, true)
|
|
||||||
{
|
|
||||||
BoundTypeDefinition = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Type _type;
|
|
||||||
public override Type Type
|
|
||||||
{
|
|
||||||
get => BoundTypeDefinition?.ScriptType ?? _type;
|
|
||||||
set => _type = Type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TableVariableSymbol : VariableSymbol
|
|
||||||
{
|
|
||||||
public Dictionary<string, VariableSymbol> Variables { get; }
|
|
||||||
|
|
||||||
public TableVariableSymbol(string name, bool local, Dictionary<string, VariableSymbol> variables)
|
|
||||||
:base (name, Type.Table, local)
|
|
||||||
{
|
|
||||||
Variables = variables;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
using Upsilon.BaseTypes;
|
||||||
|
using Upsilon.BoundTypes;
|
||||||
|
|
||||||
|
namespace Upsilon.Binder.VariableSymbols
|
||||||
|
{
|
||||||
|
public class FunctionParameterSymbol : VariableSymbol
|
||||||
|
{
|
||||||
|
public BoundTypeDefinition BoundTypeDefinition { get; }
|
||||||
|
|
||||||
|
public FunctionParameterSymbol(string name, Type type) : base(name, type, true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionParameterSymbol(string name, BoundTypeDefinition type) : base(name, type.ScriptType, true)
|
||||||
|
{
|
||||||
|
BoundTypeDefinition = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type _type;
|
||||||
|
public override Type Type
|
||||||
|
{
|
||||||
|
get => BoundTypeDefinition?.ScriptType ?? _type;
|
||||||
|
set => _type = Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using Upsilon.BaseTypes;
|
||||||
|
|
||||||
|
namespace Upsilon.Binder.VariableSymbols
|
||||||
|
{
|
||||||
|
public abstract class FunctionVariableSymbol : VariableSymbol
|
||||||
|
{
|
||||||
|
public Type ResultType { get; internal set; }
|
||||||
|
|
||||||
|
public FunctionVariableSymbol(string name, bool local, Type resultType)
|
||||||
|
: base(name, Type.Function, local)
|
||||||
|
{
|
||||||
|
ResultType = resultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract (bool IsValid, string Error, BoundExpression WrongParameter) ValidateParameters(
|
||||||
|
ImmutableArray<BoundExpression> callingParameters);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using Type = Upsilon.BaseTypes.Type;
|
||||||
|
|
||||||
|
namespace Upsilon.Binder.VariableSymbols
|
||||||
|
{
|
||||||
|
public class InternalFunctionVariableSymbol : FunctionVariableSymbol
|
||||||
|
{
|
||||||
|
public class InternalFunctionParameter
|
||||||
|
{
|
||||||
|
public InternalFunctionParameter(Type t)
|
||||||
|
{
|
||||||
|
ValidTypes = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ValidTypes { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public InternalFunctionParameter[] FunctionParameters { get; }
|
||||||
|
|
||||||
|
public InternalFunctionVariableSymbol(string name, bool local, Type resultType, InternalFunctionParameter[] functionParameters)
|
||||||
|
: base(name, local, resultType)
|
||||||
|
{
|
||||||
|
FunctionParameters = functionParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override (bool IsValid, string Error,
|
||||||
|
BoundExpression WrongParameter) ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
|
||||||
|
{
|
||||||
|
if (FunctionParameters.Length != callingParameters.Length)
|
||||||
|
{
|
||||||
|
return (false,
|
||||||
|
$"Invalid number of parameters for function '{Name}'. Expected {FunctionParameters.Length}, got {callingParameters.Length}",
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < FunctionParameters.Length; i++)
|
||||||
|
{
|
||||||
|
var functionParameter = FunctionParameters[i];
|
||||||
|
var callingParameter = callingParameters[i];
|
||||||
|
if (callingParameter.Type != Type.Unknown && callingParameter.Type != Type.Nil)
|
||||||
|
{
|
||||||
|
if ((functionParameter.ValidTypes ^ callingParameter.Type) != 0)
|
||||||
|
{
|
||||||
|
return (false,
|
||||||
|
$"Unexpected variable passed to internal function '{functionParameter}'.",
|
||||||
|
callingParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using Upsilon.BaseTypes;
|
||||||
|
|
||||||
|
namespace Upsilon.Binder.VariableSymbols
|
||||||
|
{
|
||||||
|
public class ScriptFunctionVariableSymbol : FunctionVariableSymbol
|
||||||
|
{
|
||||||
|
public ImmutableArray<VariableSymbol> Parameters { get; }
|
||||||
|
public bool IsBound { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public ScriptFunctionVariableSymbol(string name, bool local, ImmutableArray<VariableSymbol> parameters, Type resultType)
|
||||||
|
: base(name, local, resultType)
|
||||||
|
{
|
||||||
|
Parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override (bool IsValid, string Error, BoundExpression WrongParameter) ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
|
||||||
|
{
|
||||||
|
if (Parameters.Length != callingParameters.Length)
|
||||||
|
{
|
||||||
|
return (false,
|
||||||
|
$"Invalid number of parameters for function '{Name}'. Expected {Parameters.Length}, got {callingParameters.Length}",
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < Parameters.Length; i++)
|
||||||
|
{
|
||||||
|
var functionParameter = Parameters[i];
|
||||||
|
var callingParameter = callingParameters[i];
|
||||||
|
if (functionParameter.Type != Type.Unknown &&
|
||||||
|
callingParameter.Type != Type.Unknown && callingParameter.Type != Type.Nil)
|
||||||
|
{
|
||||||
|
if (callingParameter.Type != functionParameter.Type)
|
||||||
|
{
|
||||||
|
return (false, $"Invalid type for function '{Name}' at parameter '{functionParameter.Name}'. " +
|
||||||
|
$"Expected type '{functionParameter.Type}', got '{callingParameter.Type}'",
|
||||||
|
callingParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Upsilon.BaseTypes;
|
||||||
|
|
||||||
|
namespace Upsilon.Binder.VariableSymbols
|
||||||
|
{
|
||||||
|
public class TableVariableSymbol : VariableSymbol
|
||||||
|
{
|
||||||
|
public Dictionary<string, VariableSymbol> Variables { get; }
|
||||||
|
|
||||||
|
public TableVariableSymbol(string name, bool local, Dictionary<string, VariableSymbol> variables)
|
||||||
|
:base (name, Type.Table, local)
|
||||||
|
{
|
||||||
|
Variables = variables;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Upsilon.BaseTypes;
|
||||||
|
|
||||||
|
namespace Upsilon.Binder.VariableSymbols
|
||||||
|
{
|
||||||
|
public class VariableSymbol
|
||||||
|
{
|
||||||
|
public VariableSymbol(string name, Type type, bool local)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
Local = local;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Type Type { get; set; }
|
||||||
|
public bool Local { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string[] CommentValue { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
|
|
||||||
namespace Upsilon.Evaluator
|
namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Upsilon.BaseTypes.ScriptFunction;
|
||||||
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
||||||
using Upsilon.BaseTypes.UserData;
|
using Upsilon.BaseTypes.UserData;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Type = Upsilon.BaseTypes.Type;
|
using Type = Upsilon.BaseTypes.Type;
|
||||||
|
|
||||||
namespace Upsilon.Evaluator
|
namespace Upsilon.Evaluator
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
|
using Upsilon.BaseTypes.Number;
|
||||||
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
|
using Type = Upsilon.BaseTypes.Type;
|
||||||
|
|
||||||
namespace Upsilon.StandardLibraries
|
namespace Upsilon.StandardLibraries
|
||||||
{
|
{
|
||||||
|
@ -49,10 +52,11 @@ namespace Upsilon.StandardLibraries
|
||||||
foreach (var func in basicFunctions)
|
foreach (var func in basicFunctions)
|
||||||
{
|
{
|
||||||
funcs.Add(func.Key, func.Value.MethodInfoFunction);
|
funcs.Add(func.Key, func.Value.MethodInfoFunction);
|
||||||
var functionSymbol = new FunctionVariableSymbol(func.Key, true, ImmutableArray<VariableSymbol>.Empty,
|
var functionSymbol = new InternalFunctionVariableSymbol(func.Key, true,
|
||||||
func.Value.MethodInfoFunction.ReturnType.GetScriptType(), true)
|
func.Value.MethodInfoFunction.ReturnType.GetScriptType(),
|
||||||
|
func.Value.MethodInfoFunction.GetParameterTypes().Select(x =>
|
||||||
|
new InternalFunctionVariableSymbol.InternalFunctionParameter(DeriveValidTypes(x))).ToArray())
|
||||||
{
|
{
|
||||||
IsBound = true,
|
|
||||||
CommentValue = func.Value.CommentValue?.Split('\n')
|
CommentValue = func.Value.CommentValue?.Split('\n')
|
||||||
};
|
};
|
||||||
boundFuncs.Add(func.Key, functionSymbol);
|
boundFuncs.Add(func.Key, functionSymbol);
|
||||||
|
@ -69,5 +73,20 @@ namespace Upsilon.StandardLibraries
|
||||||
BoundScope.AssignToNearest(varSymbol);
|
BoundScope.AssignToNearest(varSymbol);
|
||||||
Scope.AssignToNearest(varSymbol, luaVariable);
|
Scope.AssignToNearest(varSymbol, luaVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Type DeriveValidTypes(System.Type type)
|
||||||
|
{
|
||||||
|
if (type == typeof(ScriptString))
|
||||||
|
return Type.String;
|
||||||
|
if (typeof(ScriptNumber).IsAssignableFrom(type))
|
||||||
|
return Type.Number;
|
||||||
|
if (type == typeof(ScriptBoolean))
|
||||||
|
return Type.Boolean;
|
||||||
|
if (type == typeof(IIterable))
|
||||||
|
return Type.Table | Type.UserData;
|
||||||
|
if (typeof(ScriptTable).IsAssignableFrom(type))
|
||||||
|
return Type.Table;
|
||||||
|
return Type.UserData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
|
using Upsilon.Binder.VariableSymbols;
|
||||||
|
|
||||||
namespace Upsilon.Utilities
|
namespace Upsilon.Utilities
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue