Skip to content

Commit

Permalink
refinements of clvm tools
Browse files Browse the repository at this point in the history
  • Loading branch information
kev committed Jan 16, 2024
1 parent 1195b20 commit 8d98ccb
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 64 deletions.
30 changes: 19 additions & 11 deletions CLVMDotNet/CLVMDotNet.Tools/IR/IRReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Data;
using System.Text;
using System.Linq;
using System.Numerics;
using CLVMDotNet;
using CLVMDotNet.Tools.IR;

Expand Down Expand Up @@ -99,13 +100,18 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

public static int ConsumeWhitespace(string s, int offset)
{
while (offset < s.Length && char.IsWhiteSpace(s[offset]))
while (true)
{
offset++;
}
while (offset < s.Length && char.IsWhiteSpace(s[offset]))
{
offset++;
}

if (offset >= s.Length || s[offset] != ';')
{
break;
}

if (offset < s.Length && s[offset] == ';')
{
while (offset < s.Length && s[offset] != '\n' && s[offset] != '\r')
{
offset++;
Expand Down Expand Up @@ -269,7 +275,7 @@ public static bool TryParseHex(string token, out byte[] result)
}
}

public static Tuple<Tuple<IRType, int>, byte[]>? TokenizeQuotes(string token, int offset)
public static Tuple<Tuple<BigInteger, int>, byte[]>? TokenizeQuotes(string token, int offset)
{
if (token.Length >= 2)
{
Expand All @@ -278,9 +284,9 @@ public static bool TryParseHex(string token, out byte[] result)
{
if (token[token.Length - 1] == c)
{
IRType qType = (c == '\'') ? IRType.SINGLE_QUOTE : IRType.DOUBLE_QUOTE;
BigInteger qType = (c == '\'') ? IRType.SINGLE_QUOTE : IRType.DOUBLE_QUOTE;
byte[] value = Encoding.UTF8.GetBytes(token.Substring(1, token.Length - 2));
return new Tuple<Tuple<IRType, int>, byte[]>(new Tuple<IRType, int>(qType, offset), value);
return new Tuple<Tuple<BigInteger, int>, byte[]>(new Tuple<BigInteger, int>(qType, offset), value);
}
else
{
Expand All @@ -292,7 +298,7 @@ public static bool TryParseHex(string token, out byte[] result)
return null;
}

public static Tuple<(IRType, int), string>? TokenizeSymbol(string token, int offset)
public static Tuple<(BigInteger, int), string>? TokenizeSymbol(string token, int offset)
{
return Tuple.Create((IRType.SYMBOL, offset),token);
}
Expand Down Expand Up @@ -349,13 +355,15 @@ public static bool TryParseHex(string token, out byte[] result)
public static SExp ReadIR(string s)
{
var stream = TokenStream(s);

var enumerator = stream.GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
return SExp.To(TokenizeSexp(item.token, item.offset, enumerator));
var ts = TokenizeSexp(item.token, item.offset, enumerator);
return SExp.To(ts);
}

throw new ArgumentException("unexpected end of stream");
}

Expand Down
39 changes: 17 additions & 22 deletions CLVMDotNet/CLVMDotNet.Tools/IR/IRType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,31 @@ namespace CLVMDotNet.Tools.IR;

public class IRType
{
public static IRType CONS = new IRType(Utils.ConvertToBase256("CONS")); // Equivalent to b"CONS"
public static IRType NULL = new IRType(Utils.ConvertToBase256("NULL")); // Equivalent to b"NULL"
public static IRType INT = new IRType(Utils.ConvertToBase256("INT")); // Equivalent to b"INT"
public static IRType HEX = new IRType(Utils.ConvertToBase256("HEX")); // Equivalent to b"HEX"
public static IRType QUOTES = new IRType(Utils.ConvertToBase256("QT")); // Equivalent to b"QT"
public static IRType DOUBLE_QUOTE = new IRType(Utils.ConvertToBase256("DQT")); // Equivalent to b"DQT"
public static IRType SINGLE_QUOTE = new IRType(Utils.ConvertToBase256("SQT")); // Equivalent to b"SQT"
public static IRType SYMBOL = new IRType(Utils.ConvertToBase256("SYM")); // Equivalent to b"SYM"
public static IRType OPERATOR = new IRType(Utils.ConvertToBase256("OP")); // Equivalent to b"OP"
public static IRType CODE = new IRType(Utils.ConvertToBase256("CODE")); // Equivalent to b"CODE"
public static IRType NODE = new IRType(Utils.ConvertToBase256("NODE")); // Equivalent to b"NODE"
public BigInteger _val { get; private set; }

public IRType(BigInteger val)
{
_val = val;
}
public static BigInteger CONS = Utils.ConvertToBase256("CONS"); // Equivalent to b"CONS"
public static BigInteger NULL = Utils.ConvertToBase256("NULL"); // Equivalent to b"NULL"
public static BigInteger INT = Utils.ConvertToBase256("INT"); // Equivalent to b"INT"
public static BigInteger HEX = Utils.ConvertToBase256("HEX"); // Equivalent to b"HEX"
public static BigInteger QUOTES = Utils.ConvertToBase256("QT"); // Equivalent to b"QT"
public static BigInteger DOUBLE_QUOTE = Utils.ConvertToBase256("DQT"); // Equivalent to b"DQT"
public static BigInteger SINGLE_QUOTE = Utils.ConvertToBase256("SQT"); // Equivalent to b"SQT"
public static BigInteger SYMBOL = Utils.ConvertToBase256("SYM"); // Equivalent to b"SYM"
public static BigInteger OPERATOR = Utils.ConvertToBase256("OP"); // Equivalent to b"OP"
public static BigInteger CODE = Utils.ConvertToBase256("CODE"); // Equivalent to b"CODE"
public static BigInteger NODE = Utils.ConvertToBase256("NODE"); // Equivalent to b"NODE"


public bool Listp()
public static bool Listp()
{
return false;
}

public byte[] AsAtom()
public byte[] AsAtom(BigInteger val)
{
return Casts.IntToBytes(_val);
return Casts.IntToBytes(val);
}

public int BitLength()
public static int BitLength(BigInteger val)
{
return (int)Math.Ceiling(BigInteger.Log(_val, 256) / 8);
return (int)Math.Ceiling(BigInteger.Log(val, 256) / 8);
}
}
11 changes: 5 additions & 6 deletions CLVMDotNet/CLVMDotNet.Tools/IR/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ public static BigInteger ConvertToBase256(string s)
return val;
}

public static SExp IrNew(IRType type, dynamic val, int? offset = null)
public static SExp IrNew(BigInteger type, dynamic val, int? offset = null)
{
if (offset.HasValue)
{
return SExp.To(new Tuple<BigInteger, BigInteger>(type._val, offset.Value));
return SExp.To(new Tuple<dynamic, dynamic>(type, offset));
}

return SExp.To(new Tuple<BigInteger, dynamic>(type._val, val));
return SExp.To(new Tuple<BigInteger, dynamic>(type, val));
}

public static SExp IrNew(SExp first, SExp rest)
{
return SExp.To((first, rest));
}

public static SExp IrCons(SExp first, SExp rest, int? offset = null)
public static SExp IrCons(dynamic first, dynamic rest, int? offset = null)
{
return IrNew(IRType.CONS, IrNew(first, rest), offset);
}
Expand Down Expand Up @@ -91,8 +91,7 @@ public static bool IsIr(SExp sexp)
var theType = Casts.IntFromBytes(f);
try
{
IRType t = new IRType(theType);
if (t._val == IRType.CONS._val)
if (theType == IRType.CONS)
{
if (pair.Item2.Atom != null && pair.Item2.Atom.Length == 0)
{
Expand Down
20 changes: 17 additions & 3 deletions CLVMDotNet/src/CLVMObject.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Numerics;

namespace CLVMDotNet;

using System;
Expand All @@ -9,7 +11,7 @@ namespace CLVMDotNet;
public class CLVMObject
{
public dynamic? Atom { get; set; }
public Tuple<dynamic, dynamic>? Pair { get; set; }
public Tuple<dynamic?, dynamic?>? Pair { get; set; }

public CLVMObject(dynamic? v)
{
Expand All @@ -23,7 +25,19 @@ public CLVMObject(dynamic? v)
{
//valid tuple
Atom = null;
Pair = v;

if (v is Tuple<BigInteger, BigInteger> bi)
Pair = new Tuple<dynamic?, dynamic?>(bi.Item1, bi.Item2);
else if (v is Tuple<SExp, SExp> sexp)
Pair = new Tuple<dynamic?, dynamic?>(sexp.Item1, sexp.Item2);
else if (v is Tuple<CLVMObject, CLVMObject> clvm)
Pair = new Tuple<dynamic?, dynamic?>(clvm.Item1, clvm.Item2);
else if (v is Tuple<BigInteger, int> mixint)
Pair = new Tuple<dynamic?, dynamic?>(mixint.Item1, mixint.Item2);
else
{
Pair = v;
}
}
else
{
Expand All @@ -37,7 +51,7 @@ public CLVMObject(dynamic? v)
{
throw new ArgumentException("tuples must be of size 2");
}

//v is an atom, which means it can be any type (string,byte,byte[],[],sexp etc)
Pair = null;
Atom = v;
Expand Down
102 changes: 83 additions & 19 deletions CLVMDotNet/src/HelperFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,78 @@

namespace CLVMDotNet
{

public static class HelperFunctions
{
private static byte[] nullBytes = new byte[0];

public static bool IsTuple(dynamic obj) => obj switch
private static bool IsTuple(dynamic? obj)
{
Tuple<int, int> => true,
Tuple<object,object> => true,
Tuple<BigInteger, BigInteger> => true,
_ => false
};

var isTuple = false;
Type type = obj?.GetType();


if (type != null)
{

if (!isTuple)
isTuple = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Tuple<,>);

if (!isTuple)
isTuple = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ValueTuple<,>);
}

return isTuple;
}

public static dynamic? GetLeftIfTuple(dynamic t)
{
if (IsTuple(t))
{
if (t.GetType().GetGenericTypeDefinition() == typeof(ValueTuple<,>))
{
FieldInfo item1Field = t.GetType().GetField("Item1");
if (item1Field != null)
{
return item1Field.GetValue(t);
}
}
else
{
PropertyInfo item1Property = t.GetType().GetProperty("Item1");
if (item1Property != null)
{
return item1Property.GetValue(t);
}
}
}
return null;
}

public static dynamic? GetRightIfTuple(dynamic t)
{
if (IsTuple(t))
{
if (t.GetType().GetGenericTypeDefinition() == typeof(ValueTuple<,>))
{
FieldInfo item1Field = t.GetType().GetField("Item2");
if (item1Field != null)
{
return item1Field.GetValue(t);
}
}
else
{
PropertyInfo item1Property = t.GetType().GetProperty("Item2");
if (item1Property != null)
{
return item1Property.GetValue(t);
}
}
}
return null;
}


public static dynamic? ToSexpType(dynamic? v)
{
List<dynamic> stack = new List<dynamic>() { v };
Expand All @@ -39,29 +98,34 @@ public static class HelperFunctions
continue;
}

dynamic value = stack[stack.Count - 1];
dynamic? value = stack[stack.Count - 1];
stack.RemoveAt(stack.Count - 1);

if (IsTuple(value))
{
if (value.Item2 != null)
var left = GetLeftIfTuple(value);
var right = GetRightIfTuple(value);
target = stack.Count;
stack.Add(new CLVMObject(Tuple.Create(left, right)));

if (!LooksLikeCLVMObject(right))
{
stack.Add(value.Item2);
stack.Add(right);
ops.Add((2, target)); // set right
ops.Add((0, -1)); // convert
}

if (value.Item1 != null)
if (!LooksLikeCLVMObject(left))
{
stack.Add(value.Item1);
stack.Add(left);
ops.Add((1, target)); // set left
ops.Add((0, -1)); // convert
}

continue;
}

if (value != null && value.GetType().IsArray)
else if (value != null && value.GetType().IsArray)
{
target = stack.Count;
stack.Add(new CLVMObject(nullBytes));
Expand Down Expand Up @@ -90,17 +154,17 @@ public static class HelperFunctions
{
var leftValue = new CLVMObject(stack[stack.Count - 1]);
stack.RemoveAt(stack.Count - 1);
var currentPair = ((Tuple<CLVMObject, CLVMObject>)stack[target]);
stack[target] = new Tuple<CLVMObject, CLVMObject>(leftValue, currentPair.Item2);
var currentPair = stack[target];
stack[target].Pair = Tuple.Create<dynamic,dynamic>(leftValue, currentPair.Pair.Item2);
continue;
}

if (op == 2) // set right
{
var rightValue = new CLVMObject(stack[stack.Count - 1]);
stack.RemoveAt(stack.Count - 1);
var currentPair = ((Tuple<CLVMObject, CLVMObject>)stack[target]);
stack[target] = new Tuple<CLVMObject, CLVMObject>(currentPair.Item1, rightValue);
var currentPair = stack[target];
stack[target].Pair = Tuple.Create<dynamic,dynamic>(currentPair.Pair.Item1, rightValue);
continue;
}

Expand Down Expand Up @@ -144,7 +208,7 @@ public static byte[] ConvertAtomToBytes(dynamic? v)
var s = Casts.IntToBytes(intValue);
return s;
}

if (v is BigInteger bigIntValue)
{
var s = Casts.IntToBytes(bigIntValue);
Expand Down
2 changes: 1 addition & 1 deletion CLVMDotNet/src/Serialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public static IEnumerable<byte> SexpToByteIterator(SExp sexp)
while (todoStack.Count > 0)
{
var p = todoStack.Pop();
Tuple<dynamic, dynamic>? pair = p.Pair;
Tuple<object, object>? pair = p.Pair;

if (pair != null)
{
Expand Down
2 changes: 1 addition & 1 deletion CLVMDotNet/tests/SExp/AsBin.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Xunit;
using clvm = CLVMDotNet;

namespace clvm_dotnet.tests.SExp;
namespace CLVMDotNet.Tests.SExp;
[Trait("SExp", "AsBin")]
public class AsBin
{
Expand Down
Loading

0 comments on commit 8d98ccb

Please sign in to comment.