Skip to content
15 changes: 14 additions & 1 deletion src/OneScript.Core/Commons/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,20 @@ public static void ForEach<T>(this IEnumerable<T> input, Action<T> action)
action(data);
}
}

public static string NameAndValuePresentation(string name, object value)
{
var list = new List<string>();
if (!string.IsNullOrEmpty(name))
{
list.Add(name);
}
if (value != null)
{
list.Add(value.ToString());
}
return string.Join("=", list);
}

public static bool IsMonoRuntime => Type.GetType("Mono.Runtime") != null;

}
Expand Down
11 changes: 8 additions & 3 deletions src/OneScript.Core/Contexts/BslAnnotationAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using OneScript.Commons;
using OneScript.Values;
using System;
using System.Collections.Generic;
using OneScript.Values;

namespace OneScript.Contexts
{
Expand Down Expand Up @@ -37,7 +38,7 @@ public void SetParameters(IEnumerable<BslAnnotationParameter> parameters)

public class BslAnnotationParameter
{
public BslAnnotationParameter(string name, BslPrimitiveValue value)
public BslAnnotationParameter(string name, BslPrimitiveValue value = null)
{
Name = name;
Value = value;
Expand All @@ -47,6 +48,10 @@ public BslAnnotationParameter(string name, BslPrimitiveValue value)

public BslPrimitiveValue Value { get; }

public int ConstantValueIndex { get; set; } = -1;
public override string ToString()
{
return Utils.NameAndValuePresentation(Name, Value);
}

}
}
58 changes: 58 additions & 0 deletions src/OneScript.Core/Values/BslAnnotationValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System;
using OneScript.Contexts;
using OneScript.Exceptions;
using OneScript.Localization;
using OneScript.Types;
using System.Collections.Generic;
using System.Text;

namespace OneScript.Values
{
public sealed class BslAnnotationValue : BslPrimitiveValue
{
public BslAnnotationValue(string name) {
Name = name;
}

public string Name { get; }

public List<BslAnnotationParameter> Parameters { get; } = new List<BslAnnotationParameter>();


public override int CompareTo(BslValue other) {
var msg = new BilingualString("Сравнение на больше/меньше для данного типа не поддерживается",
"Comparison for less/greater is not supported for this type");

throw new RuntimeException(msg);
}

public override bool Equals(BslValue other) {
return ReferenceEquals(this, other);
}

public override string ToString()
{
var sb = new StringBuilder("&");
sb.Append(Name);
if (Parameters.Count != 0)
{
var prefix = "(";
foreach (var parameter in Parameters)
{
sb.Append(prefix);
sb.Append(parameter);
prefix = ",";
}
sb.Append(")");
}
return sb.ToString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,29 @@ public AnnotationParameterNode() : base(NodeKind.AnnotationParameter)

protected override void OnChildAdded(BslSyntaxNode child)
{
var node = (TerminalNode) child;
if (child.Kind == NodeKind.AnnotationParameterName)
if (child.Kind == NodeKind.Annotation)
{
Name = node.Lexem.Content;
AnnotationNode = (AnnotationNode)child;
}
if (child.Kind == NodeKind.AnnotationParameterValue)
else
{
Value = node.Lexem;
var node = (TerminalNode)child;
if (child.Kind == NodeKind.AnnotationParameterName)
{
Name = node.Lexem.Content;
}
if (child.Kind == NodeKind.AnnotationParameterValue)
{
Value = node.Lexem;
}
}
}

public string Name { get; private set; }

public Lexem Value { get; private set; }

public AnnotationNode AnnotationNode { get; private set; }

}
}
22 changes: 16 additions & 6 deletions src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,13 +541,18 @@ private void BuildAnnotations()
{
while (_lastExtractedLexem.Type == LexemType.Annotation)
{
var node = new AnnotationNode(NodeKind.Annotation, _lastExtractedLexem);
var node = BuildAnnotationDefinition();
_annotations.Add(node);
NextLexem();
BuildAnnotationParameters(node);
}
}

private AnnotationNode BuildAnnotationDefinition() {
var node = new AnnotationNode(NodeKind.Annotation, _lastExtractedLexem);
NextLexem();
BuildAnnotationParameters(node);
return node;
}


private void BuildAnnotationParameters(AnnotationNode annotation)
{
if (_lastExtractedLexem.Token != Token.OpenPar)
Expand Down Expand Up @@ -599,11 +604,16 @@ private void BuildAnnotationParameter(AnnotationNode annotation)

private bool BuildAnnotationParamValue(AnnotationParameterNode annotationParam)
{
if (_lastExtractedLexem.Type == LexemType.Annotation) {
var annotation = BuildAnnotationDefinition();
annotationParam.AddChild(annotation);
return true;
}
return BuildDefaultParameterValue(annotationParam, NodeKind.AnnotationParameterValue);
}

#endregion

private void BuildCodeBatch(params Token[] endTokens)
{
PushStructureToken(endTokens);
Expand Down
10 changes: 10 additions & 0 deletions src/OneScript.Native/Compiler/CompilerHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ private static IEnumerable<BslAnnotationParameter> GetAnnotationParameters(Annot
private static BslAnnotationParameter MakeAnnotationParameter(AnnotationParameterNode param)
{
BslAnnotationParameter result;
if (param.AnnotationNode != null)
{
var runtimeValue = new BslAnnotationValue(param.AnnotationNode.Name);
foreach (var child in param.AnnotationNode.Children)
{
runtimeValue.Parameters.Add(MakeAnnotationParameter((AnnotationParameterNode)child));
}
result = new BslAnnotationParameter(param.Name, runtimeValue);
}
else
if (param.Value.Type != LexemType.NotALexem)
{
var runtimeValue = ValueFromLiteral(param.Value);
Expand Down
46 changes: 30 additions & 16 deletions src/OneScript.StandardLibrary/Reflector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,27 +163,41 @@ private static ValueTable CreateAnnotationTable(BslAnnotationAttribute[] annotat
{
annotationRow.Set(annotationNameColumn, ValueFactory.Create(annotation.Name));
}
var parametersTable = new ValueTable();
var parameterNameColumn = parametersTable.Columns.Add("Имя");
var parameterValueColumn = parametersTable.Columns.Add("Значение");

var parametersTable = FillAnnotationParameters(annotation.Parameters);
annotationRow.Set(annotationParamsColumn, parametersTable);
if (annotation.Parameters.Any())
{
}

foreach (var annotationParameter in annotation.Parameters)
{
var parameterRow = parametersTable.Add();
if (annotationParameter.Name != null)
{
parameterRow.Set(parameterNameColumn, ValueFactory.Create(annotationParameter.Name));
}
parameterRow.Set(parameterValueColumn, annotationParameter.Value);
}
return annotationsTable;
}

private static ValueTable FillAnnotationParameters(IEnumerable<BslAnnotationParameter> parameters)
{
var parametersTable = new ValueTable();
var parameterNameColumn = parametersTable.Columns.Add("Имя");
var parameterValueColumn = parametersTable.Columns.Add("Значение");

foreach (var annotationParameter in parameters)
{
var parameterRow = parametersTable.Add();
if (annotationParameter.Name != null)
{
parameterRow.Set(parameterNameColumn, ValueFactory.Create(annotationParameter.Name));
}
if (annotationParameter.Value is BslAnnotationValue annotationValue)
{
var expandedValue = EmptyAnnotationsTable();
var row = expandedValue.Add();
row.Set(expandedValue.Columns.FindColumnByName("Имя"), ValueFactory.Create(annotationValue.Name));
row.Set(expandedValue.Columns.FindColumnByName("Параметры"), FillAnnotationParameters(annotationValue.Parameters));
parameterRow.Set(parameterValueColumn, row);
}
else
{
parameterRow.Set(parameterValueColumn, annotationParameter.Value);
}
}

return annotationsTable;
return parametersTable;
}

private static bool MethodExistsForType(BslTypeValue type, string methodName)
Expand Down
31 changes: 22 additions & 9 deletions src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This Source Code Form is subject to the terms of the
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using OneScript.Compilation;
using OneScript.Compilation.Binding;
using OneScript.Contexts;
Expand Down Expand Up @@ -1170,23 +1171,35 @@ private IEnumerable<BslAnnotationParameter> GetAnnotationParameters(AnnotationNo

private BslAnnotationParameter MakeAnnotationParameter(AnnotationParameterNode param)
{
BslAnnotationParameter result;
var runtimeValue = MakeAnnotationParameterValueConstant(param);
return new BslAnnotationParameter(param.Name, runtimeValue);
}

private BslPrimitiveValue MakeAnnotationParameterValueConstant(AnnotationParameterNode param)
{
if (param.AnnotationNode != null)
{
var runtimeValue = new BslAnnotationValue(param.AnnotationNode.Name);
foreach (var child in param.AnnotationNode.Children)
{
var parameter = (AnnotationParameterNode)child;
var parameterValue = MakeAnnotationParameterValueConstant(parameter);
runtimeValue.Parameters.Add(new BslAnnotationParameter(parameter.Name, parameterValue));
}
return runtimeValue;
}
else
if (param.Value.Type != LexemType.NotALexem)
{
var constDef = CreateConstDefinition(param.Value);
var constNumber = GetConstNumber(constDef);
var runtimeValue = _module.Constants[constNumber];
result = new BslAnnotationParameter(param.Name, runtimeValue)
{
ConstantValueIndex = constNumber
};
return runtimeValue;
}
else
{
result = new BslAnnotationParameter(param.Name, null);
return null;
}

return result;
}

private IEnumerable<BslAnnotationAttribute> GetAnnotations(AnnotatableNode parent)
Expand Down Expand Up @@ -1235,7 +1248,7 @@ private static ConstDefinition CreateConstDefinition(in Lexem lex)
};
return cDef;
}

private int GetConstNumber(in ConstDefinition cDef)
{
var idx = _constMap.IndexOf(cDef);
Expand Down
17 changes: 17 additions & 0 deletions src/ScriptEngine/Machine/AnnotationDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
using System;

namespace ScriptEngine.Machine
{
public struct AnnotationDefinition
{
public string Name;
public AnnotationParameter[] Parameters;
public readonly int ParamCount => Parameters?.Length ?? 0;
}
}
23 changes: 23 additions & 0 deletions src/ScriptEngine/Machine/AnnotationParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
using OneScript.Commons;

namespace ScriptEngine.Machine
{
public struct AnnotationParameter
{
public string Name;

public IValue RuntimeValue;

public override readonly string ToString()
{
return Utils.NameAndValuePresentation(Name, RuntimeValue);
}

}
}
Loading
Loading