From 09023ddc8653a02d57340f72df4cfc48073a0bef Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Tue, 14 Oct 2025 00:47:53 -0400 Subject: [PATCH] improvements to Zq scripting runtime --- mocha-common | 2 +- .../lib/Mocha.Core/KnownRelationshipGuids.cs | 8 +- .../BuildAttributeMethodImplementation.cs | 57 +++--- mocha-dotnet/src/lib/Mocha.Core/Oms.cs | 22 ++- .../src/lib/Mocha.Core/OmsMethodBuilder.cs | 19 ++ .../src/lib/Mocha.Core/Oop/LogicalOperator.cs | 9 +- mocha-dotnet/src/lib/Mocha.Zq/IZqMethod.cs | 1 + mocha-dotnet/src/lib/Mocha.Zq/ZqDataType.cs | 27 ++- .../src/lib/Mocha.Zq/ZqMethodReference.cs | 1 + .../src/lib/Mocha.Zq/ZqOmsExtensions.cs | 168 ++++++++++++++++++ mocha-dotnet/src/lib/Mocha.Zq/ZqParameter.cs | 33 +++- mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs | 21 ++- .../tests/Mocha.Zq.Tests/MathTests.cs | 39 +++- 13 files changed, 357 insertions(+), 50 deletions(-) create mode 100644 mocha-dotnet/src/lib/Mocha.Zq/ZqOmsExtensions.cs diff --git a/mocha-common b/mocha-common index 6ee9931..2cedd66 160000 --- a/mocha-common +++ b/mocha-common @@ -1 +1 @@ -Subproject commit 6ee9931cff2ac2645df584f7d6d1c8f39e0fd768 +Subproject commit 2cedd6600d418723ec97f51b28cd9e1c31ff8d30 diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs index 36ec357..41f3c14 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs @@ -313,8 +313,12 @@ namespace Mocha.Core public static Guid Audit_Line__has__Instance { get; } = new Guid("{c91807ed-0d73-4729-990b-d90750764fb5}"); public static Guid Audit_Line__has__User { get; } = new Guid("{7c1e048d-3dcb-4473-9f2e-e21014a76aa5}"); - public static Guid Method__has__Method_Parameter { get; } = new Guid("{c455dc79-ba9b-4a7c-af8e-9ca59dbe511f}"); - public static Guid Method_Parameter__for__Method { get; } = new Guid("{0bcb6e5b-5885-4747-843c-ed4c3d3dc234}"); + public static Guid Method_with_Static_and_Parms__uses_parm__Work_Data { get; } = new Guid("{5c7eafbe-952e-4720-b2ab-553414c274fc}"); + public static Guid Work_Data__parm_used_by__Method_with_Static_and_Parms { get; } = new Guid("{b11e9dfb-0755-4d59-bd26-f53c2f4f2454}"); + + public static Guid Method_with_Static_and_Parms__uses_required_parm__Work_Data { get; } = new Guid("{eeb6d2b5-48a7-4323-a9b0-e062010f681a}"); + public static Guid Work_Data__required_parm_used_by__Method_with_Static_and_Parms { get; } = new Guid("{d39ddadf-1497-4c7b-b29a-7c7668a6298a}"); + public static Guid Method__returns__Attribute { get; } = new Guid("{eb015d32-0d4f-4647-b9b8-715097f4434b}"); public static Guid Detail_Page_Component__has_caption__Translation { get; } = new Guid("{4a15fa44-fb7b-4e26-8ce2-f36652792b48}"); diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildAttributeMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildAttributeMethodImplementation.cs index 3c6f5bb..ab9005e 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildAttributeMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildAttributeMethodImplementation.cs @@ -31,34 +31,51 @@ public class BuildAttributeMethodImplementation : MethodImplementation } // InstanceHandle forInstance = (InstanceHandle) context.GetWorkData(irForClass); - object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value - if (value is string) + if (oms.IsInstanceOf(returnsAttribute, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) { - IEnumerable buildsWithRambs = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component)); - foreach (InstanceHandle ihComponent in buildsWithRambs) - { - InstanceHandle ihRamb = oms.GetRelatedInstance(ihComponent, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method_Component__uses__Executable_returning_Attribute)); - object? val = null; - - if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Attribute))) - { - val = null; - } - else if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Executable))) - { - InstanceHandle wd = oms.Execute(context, ihRamb); - val = context.GetWorkData(wd); - } + object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value - if (val is string) + if (value is string) + { + IEnumerable buildsWithRambs = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component)); + foreach (InstanceHandle ihComponent in buildsWithRambs) { - value = ((string)value) + (string)val; + InstanceHandle ihRamb = oms.GetRelatedInstance(ihComponent, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method_Component__uses__Executable_returning_Attribute)); + object? val = null; + + if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Attribute))) + { + val = null; + } + else if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Executable))) + { + InstanceHandle wd = oms.Execute(context, ihRamb); + val = context.GetWorkData(wd); + } + + if (val is string) + { + value = ((string)value) + (string)val; + } } } + context.SetWorkData(returnsAttribute, value); } + else if (oms.IsInstanceOf(returnsAttribute, oms.GetInstance(KnownInstanceGuids.Classes.NumericAttribute))) + { + object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Numeric.Value)); // initial value - context.SetWorkData(returnsAttribute, value); + if (value is decimal) + { + context.SetWorkData(returnsAttribute, value); + } + } + else + { + throw new NotImplementedException(); + } + return returnsAttribute; } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 48c9b8c..732cbdd 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -26,6 +26,7 @@ using MBS.Core.Collections; using MBS.Core.Extensibility; using Mocha.Core.Logging; using Mocha.Core.Oop; +using Mocha.Core.Oop.Methods; using Mocha.Core.Responses; using Mocha.Core.UI; @@ -266,6 +267,7 @@ public abstract class Oms UpdateSyntacticSugar(typeof(KnownInstanceGuids.AccessModifiers)); UpdateSyntacticSugar(typeof(KnownInstanceGuids.RelationalOperators)); UpdateSyntacticSugar(typeof(KnownInstanceGuids.ArithmeticOperators)); + UpdateSyntacticSugar(typeof(KnownInstanceGuids.LogicalOperators)); } } @@ -2455,8 +2457,7 @@ public abstract class Oms { foreach (InstanceHandle trueCondition in trueConditions) { - InstanceHandle ret = Execute(context, trueCondition); - object? retval = context.GetWorkData(ret); + object? retval = Evaluate(context, trueCondition, InstanceHandle.Empty); if (retval is bool && ((bool)retval)) { value = true; @@ -2708,4 +2709,21 @@ public abstract class Oms } return ih; } + + public InstanceHandle GetMethodParameter(Method method, string name) + { + IEnumerable optionalParms = GetRelatedInstances(method, GetInstance(KnownRelationshipGuids.Method_with_Static_and_Parms__uses_parm__Work_Data)); + IEnumerable requiredParms = GetRelatedInstances(method, GetInstance(KnownRelationshipGuids.Method_with_Static_and_Parms__uses_required_parm__Work_Data)); + IEnumerable parms = optionalParms.Union(requiredParms); + + foreach (InstanceHandle parm in parms) + { + string l_name = GetAttributeValue(parm, GetInstance(KnownAttributeGuids.Text.Name)); + if (name.Equals(l_name)) + { + return parm; + } + } + return InstanceHandle.Empty; + } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs index 01a0b31..bd06ae5 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs @@ -132,6 +132,25 @@ public class OmsMethodBuilder return new BuildAttributeMethod(method); } + public BuildAttributeMethod CreateBuildAttributeMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, InstanceHandle returnsAttribute, object? initialValue = null) + { + InstanceHandle method = CreateMethodBase(Oms.GetInstance(KnownInstanceGuids.MethodClasses.BuildAttributeMethod), forClassInstance, verb, name, accessModifier, isStatic); + Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__returns__Attribute), returnsAttribute); + if (initialValue is string strval) + { + Oms.SetAttributeValue(method, Oms.GetInstance(KnownAttributeGuids.Text.Value), strval); + } + else if (initialValue is decimal numval) + { + Oms.SetAttributeValue(method, Oms.GetInstance(KnownAttributeGuids.Numeric.Value), numval); + } + else + { + + } + return new BuildAttributeMethod(method); + } + public GetAttributeBySystemRoutineMethod CreateGetAttributeBySystemRoutineMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, InstanceHandle returnsAttribute, SystemAttributeRoutine usesSystemAttributeRoutine) { return CreateGetAttributeBySystemRoutineMethod(forClassInstance, verb, name, accessModifier, isStatic, Guid.NewGuid(), returnsAttribute, usesSystemAttributeRoutine); diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/LogicalOperator.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/LogicalOperator.cs index d4cd3bf..ac8a55a 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oop/LogicalOperator.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/LogicalOperator.cs @@ -20,6 +20,13 @@ namespace Mocha.Core.Oop; public class LogicalOperator : BooleanOperator { - public override Guid ClassId => KnownInstanceGuids.Classes.LogicalOperator; + public override Guid ClassId => KnownInstanceGuids.Classes.LogicalOperator; internal LogicalOperator(InstanceHandle handle) : base(handle) { } + + public static LogicalOperator EqualTo { get; internal set; } = null; + public static LogicalOperator NotEqualTo { get; internal set; } = null; + public static LogicalOperator GreaterThan { get; internal set; } = null; + public static LogicalOperator LessThan { get; internal set; } = null; + public static LogicalOperator GreaterThanOrEqualTo { get; internal set; } = null; + public static LogicalOperator LessThanOrEqualTo { get; internal set; } = null; } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Zq/IZqMethod.cs b/mocha-dotnet/src/lib/Mocha.Zq/IZqMethod.cs index 7aaec69..91fb9fd 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/IZqMethod.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/IZqMethod.cs @@ -7,4 +7,5 @@ public interface IZqMethod string Name { get; set; } ZqDataType ReturnDataType { get; set; } ZqMethodCall? Executable { get; } + ZqParameter.ZqParameterCollection Parameters { get; } } diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqDataType.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqDataType.cs index eed2747..ee9d0fc 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/ZqDataType.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqDataType.cs @@ -12,7 +12,7 @@ public struct ZqDataType public string Name { get; } public bool IsArray { get; } - + private static readonly string[] attributeTypeNames = new string[] { "text", "boolean", "integer", "date" @@ -44,23 +44,32 @@ public struct ZqDataType return new ZqDataType(name, isArray); } - public override string ToString() - { + public override string ToString() + { string str = Name; if (IsArray) { str += "*"; } - return str; - } + return str; + } - public override bool Equals([NotNullWhen(true)] object? obj) - { + public override bool Equals([NotNullWhen(true)] object? obj) + { if (obj is ZqDataType zqd) { return this.Name.Equals(zqd.Name) && this.IsArray == zqd.IsArray; } - return false; - } + return false; + } + + public static bool operator ==(ZqDataType left, ZqDataType right) + { + return left.Equals(right); + } + public static bool operator !=(ZqDataType left, ZqDataType right) + { + return !left.Equals(right); + } } diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqMethodReference.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqMethodReference.cs index a6ecf1a..622bf55 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/ZqMethodReference.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqMethodReference.cs @@ -8,6 +8,7 @@ public class ZqMethodReference : ZqExpression, IZqMethod public string Name { get; set; } public ZqDataType ReturnDataType { get; set; } public ZqMethodCall? Executable { get { return null; }} + public ZqParameter.ZqParameterCollection Parameters { get; } = new ZqParameter.ZqParameterCollection(); public ZqMethodReference(string className, string methodName) { diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqOmsExtensions.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqOmsExtensions.cs new file mode 100644 index 0000000..9930862 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqOmsExtensions.cs @@ -0,0 +1,168 @@ +using Mocha.Core; +using Mocha.Core.Oop; +using Mocha.Core.Oop.Methods; +using Mocha.Zq.Methods; + +namespace Mocha.Zq; + +public static class ZqOmsExtensions +{ + public static object? LoadZq(this Oms oms, ZqObject obj) + { + if (obj is ZqClass clasz) + { + InstanceHandle ih = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.Classes.Class)); + oms.SetAttributeValue(ih, oms.GetInstance(KnownAttributeGuids.Text.Name), clasz.Name); + ApplyAccessModifier(oms, clasz, ih); + + foreach (ZqMethod method in clasz.Functions) + { + Dictionary createdParms = new Dictionary(); + InstanceHandle ihMethod = InstanceHandle.Empty; + if (method is ZqConditionalSelectAttributeMethod) + { + ihMethod = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.MethodClasses.ConditionalSelectAttributeMethod)); + } + + if (ihMethod != InstanceHandle.Empty) + { + oms.SetAttributeValue(ihMethod, oms.GetInstance(KnownAttributeGuids.Text.Name), method.Name); + oms.AssignRelationship(ih, oms.GetInstance(KnownRelationshipGuids.Class__has__Method), ihMethod); + + foreach (ZqParameter parm in method.Parameters) + { + if (parm.DataType == ZqDataType.Text) + { + InstanceHandle parmInst = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute)); + oms.SetAttributeValue(parmInst, oms.GetInstance(KnownAttributeGuids.Text.Name), parm.Name); + oms.AssignRelationship(ihMethod, oms.GetInstance(KnownRelationshipGuids.Method_with_Static_and_Parms__uses_parm__Work_Data), parmInst); + createdParms[parm] = parmInst; + } + else if (parm.DataType == ZqDataType.Integer) + { + InstanceHandle parmInst = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.Classes.NumericAttribute)); + oms.SetAttributeValue(parmInst, oms.GetInstance(KnownAttributeGuids.Text.Name), parm.Name); + oms.AssignRelationship(ihMethod, oms.GetInstance(KnownRelationshipGuids.Method_with_Static_and_Parms__uses_parm__Work_Data), parmInst); + createdParms[parm] = parmInst; + } + } + + if (method is ZqConditionalSelectAttributeMethod sac) + { + foreach (ZqConditionalSelectAttributeCase _case in sac.Cases) + { + InstanceHandle ihCase = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.Classes.ConditionalSelectAttributeCase)); + + foreach (ZqCondition condition in _case.TrueConditions) + { + if (method.Parameters.Contains(condition.Variable)) + { + Core.Oop.BooleanOperator? booleanOp = null; + InstanceHandle attr = createdParms[method.Parameters[condition.Variable]]; + if (condition.Operator == "==") + { + booleanOp = Core.Oop.LogicalOperator.EqualTo; + } + else if (condition.Operator == "!=") + { + booleanOp = Core.Oop.LogicalOperator.NotEqualTo; + } + else if (condition.Operator == ">") + { + booleanOp = Core.Oop.LogicalOperator.GreaterThan; + } + else if (condition.Operator == "<") + { + booleanOp = Core.Oop.LogicalOperator.LessThan; + } + else if (condition.Operator == ">=") + { + booleanOp = Core.Oop.LogicalOperator.GreaterThanOrEqualTo; + } + else if (condition.Operator == "<=") + { + booleanOp = Core.Oop.LogicalOperator.LessThanOrEqualTo; + } + + BuildAttributeMethod ba = oms.MethodBuilder.CreateBuildAttributeMethod(ih, "__compiled", String.Format("trueCondition{0}value2", _case.TrueConditions.IndexOf(condition)), Core.Oop.AccessModifier.Private, true, oms.GetInstance(KnownAttributeGuids.Numeric.PrimaryOperandValue), Decimal.Parse(condition.Value)); + ReturnAttributeMethodBinding ramb = ba.CreateMethodBinding(oms); + + EvaluateBooleanExpressionMethod trueCondition = oms.MethodBuilder.CreateEvaluateBooleanExpressionMethod(ih, "__compiled", String.Format("trueCondition{0}", _case.TrueConditions.IndexOf(condition)), Core.Oop.AccessModifier.Private, true, oms.GetInstance(KnownAttributeGuids.Boolean.EvaluateWorkSet), attr, booleanOp, ramb); + oms.AssignRelationship(ihCase, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_true_condition__Executable_returning_Work_Data), trueCondition.CreateMethodBinding(oms)); + } + } + foreach (ZqCondition condition in _case.FalseConditions) + { + if (method.Parameters.Contains(condition.Variable)) + { + Core.Oop.BooleanOperator? booleanOp = null; + InstanceHandle attr = createdParms[method.Parameters[condition.Variable]]; + if (condition.Operator == "==") + { + booleanOp = Core.Oop.LogicalOperator.EqualTo; + } + else if (condition.Operator == "!=") + { + booleanOp = Core.Oop.LogicalOperator.NotEqualTo; + } + else if (condition.Operator == ">") + { + booleanOp = Core.Oop.LogicalOperator.GreaterThan; + } + else if (condition.Operator == "<") + { + booleanOp = Core.Oop.LogicalOperator.LessThan; + } + else if (condition.Operator == ">=") + { + booleanOp = Core.Oop.LogicalOperator.GreaterThanOrEqualTo; + } + else if (condition.Operator == "<=") + { + booleanOp = Core.Oop.LogicalOperator.LessThanOrEqualTo; + } + + BuildAttributeMethod ba = oms.MethodBuilder.CreateBuildAttributeMethod(ih, "__compiled", String.Format("falseCondition{0}value2", _case.FalseConditions.IndexOf(condition)), Core.Oop.AccessModifier.Private, true, oms.GetInstance(KnownAttributeGuids.Numeric.PrimaryOperandValue), Decimal.Parse(condition.Value)); + ReturnAttributeMethodBinding ramb = ba.CreateMethodBinding(oms); + + EvaluateBooleanExpressionMethod trueCondition = oms.MethodBuilder.CreateEvaluateBooleanExpressionMethod(ih, "__compiled", String.Format("falseCondition{0}", _case.FalseConditions.IndexOf(condition)), Core.Oop.AccessModifier.Private, true, oms.GetInstance(KnownAttributeGuids.Boolean.EvaluateWorkSet), attr, booleanOp, ramb); + oms.AssignRelationship(ihCase, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_false_condition__Executable_returning_Work_Data), trueCondition.CreateMethodBinding(oms)); + } + } + oms.AssignRelationship(ihMethod, oms.GetInstance(KnownRelationshipGuids.Conditional_Select_Attribute_Method__has__Conditional_Select_Attribute_Case), ihCase); + } + } + } + } + return new Mocha.Core.Oop.Class(ih); + } + return null; + } + + private static void ApplyAccessModifier(Oms oms, ZqClass clasz, InstanceHandle ih) + { + switch (clasz.AccessModifier) + { + case ZqAccessModifier.Public: + { + oms.AssignRelationship(ih, oms.GetInstance(KnownRelationshipGuids.Metadata_With_Access_Modifier__has__Access_Modifier), oms.GetInstance(KnownInstanceGuids.AccessModifiers.Public)); + break; + } + case ZqAccessModifier.Private: + { + oms.AssignRelationship(ih, oms.GetInstance(KnownRelationshipGuids.Metadata_With_Access_Modifier__has__Access_Modifier), oms.GetInstance(KnownInstanceGuids.AccessModifiers.Private)); + break; + } + case ZqAccessModifier.Protected: + { + oms.AssignRelationship(ih, oms.GetInstance(KnownRelationshipGuids.Metadata_With_Access_Modifier__has__Access_Modifier), oms.GetInstance(KnownInstanceGuids.AccessModifiers.Protected)); + break; + } + // default: + // { + // oms.AssignRelationship(ih, oms.GetInstance(KnownRelationshipGuids.Metadata_With_Access_Modifier__has__Access_Modifier), oms.GetInstance(KnownInstanceGuids.AccessModifiers.RootA2)); + // break; + // } + } + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqParameter.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqParameter.cs index fd2534d..dafebaa 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/ZqParameter.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqParameter.cs @@ -7,11 +7,38 @@ public class ZqParameter public class ZqParameterCollection : System.Collections.ObjectModel.Collection { + private Dictionary _itemsByName = new Dictionary(); + public bool Contains(string name) + { + return _itemsByName.ContainsKey(name); + } - - } + public ZqParameter this[string name] + { + get + { + return _itemsByName[name]; + } + } - public string Name { get; set; } + protected override void ClearItems() + { + base.ClearItems(); + _itemsByName.Clear(); + } + protected override void InsertItem(int index, ZqParameter item) + { + base.InsertItem(index, item); + _itemsByName[item.Name] = item; + } + protected override void RemoveItem(int index) + { + _itemsByName.Remove(this[index].Name); + base.RemoveItem(index); + } + } + + public string Name { get; set; } public ZqDataType DataType { get; set; } public ZqParameter(string name, ZqDataType dataType) diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs index c73189d..d85b46c 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs @@ -449,6 +449,7 @@ public class ZqParser private ZqMethod? ParseFunction2(string pp, ref int j, ref ZqDefParms defparms) { + ZqMethod? retval = null; string functionName = ReadUntil(pp, ref j, '(', false).Trim(); List parmListList = new List(); string parmlist = ReadUntil(pp, ref j, ')', false); @@ -524,7 +525,7 @@ public class ZqParser object val = ParseValue(value); ZqMethod func = new ZqSimpleReturnMethod(functionName, val); func.ReturnDataType = ZqDataType.Parse(returnDataType); - return func; + retval = func; } else if (!funcBody.Contains("\n")) { @@ -536,13 +537,13 @@ public class ZqParser object? val = ParseValue(value); if (val is string) { - return new ZqBuildAttributeMethod(functionName, val); + retval = new ZqBuildAttributeMethod(functionName, val); } else if (val is ZqObject) { ZqMethod func = new ZqSimpleReturnMethod(functionName, (ZqObject)val); func.ReturnDataType = ZqDataType.Parse(returnDataType); - return func; + retval = func; } } else @@ -565,7 +566,7 @@ public class ZqParser { ((IZqMethod)expr).Name = functionName; ((IZqMethod)expr).ReturnDataType = ZqDataType.Parse(returnDataType); - return (ZqMethod)expr; + retval = (ZqMethod)expr; } else if (expr == null) { @@ -610,7 +611,7 @@ public class ZqParser object rv = null; if (context.Variables.ContainsKey(varr.Name)) { - return new ZqBuildAttributeMethod(functionName, context.Variables[varr.Name]); + retval = new ZqBuildAttributeMethod(functionName, context.Variables[varr.Name]); } else { @@ -630,7 +631,15 @@ public class ZqParser } } } - return null; + + if (retval != null) + { + foreach (ZqParameter parm in parmListList) + { + retval.Parameters.Add(parm); + } + } + return retval; } private object? ParseValue(string value) diff --git a/mocha-dotnet/tests/Mocha.Zq.Tests/MathTests.cs b/mocha-dotnet/tests/Mocha.Zq.Tests/MathTests.cs index e75e38b..28c3af1 100644 --- a/mocha-dotnet/tests/Mocha.Zq.Tests/MathTests.cs +++ b/mocha-dotnet/tests/Mocha.Zq.Tests/MathTests.cs @@ -1,4 +1,6 @@ using System; +using Mocha.Core; +using Mocha.Core.Oop; using Mocha.Zq.Methods; namespace Mocha.Zq.Tests; @@ -33,15 +35,40 @@ public class MathTests Assert.That(zql.Functions.Count, Is.EqualTo(1)); Assert.That(zql.Functions[0].Name, Is.EqualTo("gcd")); Assert.That(zql.Functions[0], Is.TypeOf()); + Assert.That(zql.Functions[0].Parameters.Count, Is.EqualTo(2)); - /* + Oms oms = new Mocha.Testing.EmbeddedMiniOms(); + oms.Initialize(); - InstanceHandle c_GCD = Oms.GetInstanceByName(Oms.GetInstance(KnownInstanceGuids.Classes.Class), "GreatestCommonDivisor"); - Assert.That(c_GCD, Is.Not.EqualTo(InstanceHandle.Empty)); + Mocha.Core.Oop.Class? clasz = oms.LoadZq(zql) as Mocha.Core.Oop.Class; + Assert.That(clasz, Is.Not.Null); - InstanceHandle i_GcdMethod = zq.GetMethod("GreatestCommonDivisor.gcd"); - Assert.That(i_GcdMethod, Is.Not.EqualTo(InstanceHandle.Empty)); - */ + if (clasz != null) + { + Assert.That(oms.GetAttributeValue(clasz, oms.GetInstance(KnownAttributeGuids.Text.Name)), Is.EqualTo("GreatestCommonDivisor")); + + InstanceHandle c_GCD = oms.GetInstanceByName(oms.GetInstance(KnownInstanceGuids.Classes.Class), "GreatestCommonDivisor"); + Assert.That(c_GCD, Is.Not.EqualTo(InstanceHandle.Empty)); + + Core.Oop.Methods.ConditionalSelectAttributeMethod? i_GcdMethod = oms.GetMethod(c_GCD, null, "gcd") as Core.Oop.Methods.ConditionalSelectAttributeMethod; + Assert.That(i_GcdMethod, Is.Not.Null); + + InstanceHandle parmA = oms.GetMethodParameter(i_GcdMethod, "p"); + InstanceHandle parmB = oms.GetMethodParameter(i_GcdMethod, "q"); + + ReturnAttributeMethodBinding ramb = i_GcdMethod.CreateMethodBinding(oms, new KeyValuePair[] + { + new KeyValuePair(parmA, 4), + new KeyValuePair(parmB, 16) + }); + + OmsContext context = oms.CreateContext(); + + InstanceHandle workSet = oms.Execute(context, ramb); + object? retval = context.GetWorkData(workSet); + + Assert.That(retval, Is.EqualTo(4)); + } } }