Update to version 1.0.0 #3
10 changed files with 375 additions and 110 deletions
|
@ -2,5 +2,4 @@ FileVersion = 1
|
|||
|
||||
[Project]
|
||||
Name = "Bofa"
|
||||
TargetType = "BeefLib"
|
||||
StartupObject = "Bofa.Program"
|
||||
|
|
66
src/Bofa.bf
66
src/Bofa.bf
|
@ -5,7 +5,18 @@ using System.Collections;
|
|||
|
||||
class Bofa
|
||||
{
|
||||
private String _line = null; //The actual line
|
||||
private String __line = null; //The actual line
|
||||
private String _line
|
||||
{
|
||||
get
|
||||
{
|
||||
return __line;
|
||||
}
|
||||
set
|
||||
{
|
||||
__line = value;
|
||||
}
|
||||
}
|
||||
private Bofa _lastObject = null; //If we are a container we keep track of the last container inside of us
|
||||
|
||||
public StringView Name;
|
||||
|
@ -136,11 +147,13 @@ class Bofa
|
|||
{
|
||||
if(_line != null)
|
||||
delete _line;
|
||||
|
||||
if(Type == .Text)
|
||||
delete Value.Text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ~this()
|
||||
{
|
||||
if(_line != null)
|
||||
|
@ -183,4 +196,55 @@ class Bofa
|
|||
Value.Object[view] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ref Bofa this[int view]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
Runtime.Assert(Type == .Array);
|
||||
Runtime.Assert(Value.Array.Count > view);
|
||||
return ref Value.Array[view];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
return ref Value.Array[view];
|
||||
}
|
||||
|
||||
[Checked]
|
||||
set
|
||||
{
|
||||
Runtime.Assert(Type == .Array);
|
||||
Runtime.Assert(Value.Array.Count > view);
|
||||
Value.Array[view] = value;
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
set
|
||||
{
|
||||
Value.Array[view] = value;
|
||||
}
|
||||
}
|
||||
|
||||
///Get the value if the object is a container
|
||||
public Result<Bofa> Get(StringView pKey)
|
||||
{
|
||||
if(Type != .Object)
|
||||
return .Err;
|
||||
if(!Value.Object.ContainsKey(pKey))
|
||||
return .Err;
|
||||
return Value.Object[pKey];
|
||||
}
|
||||
|
||||
///Get the value if the object is a container
|
||||
public Result<Bofa> Get(int pIndex)
|
||||
{
|
||||
if(Type != .Array)
|
||||
return .Err;
|
||||
if(!(Value.Array.Count > pIndex))
|
||||
return .Err;
|
||||
return Value.Array[pIndex];
|
||||
}
|
||||
}
|
|
@ -32,31 +32,32 @@ class BofaParser
|
|||
while (reader.Peek() case .Ok) //This might technically cause an issue when there is data added to the stream while we where busy processing, but if you hook this up to a network stream you deserve this happening to you
|
||||
{
|
||||
String l = new .();
|
||||
|
||||
if (reader.ReadLine(l) case .Err)
|
||||
{ //Despite data being here, we cannot read it
|
||||
delete l;
|
||||
pErrors.Add(-2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var entry = ParseLine(l, line);
|
||||
if(!(entry.Type == .Bofa || entry.Type == .Text))
|
||||
if (!(entry.Type == .Bofa || entry.Type == .Text))
|
||||
delete l; //In these cases we have no useable data
|
||||
if(entry.Type == .Empty)
|
||||
if (entry.Type == .Empty)
|
||||
{
|
||||
line++;
|
||||
continue;
|
||||
}
|
||||
if(entry.Type == .Error)
|
||||
if (entry.Type == .Error)
|
||||
{
|
||||
pErrors.Add(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
//If we are on the lowest level we can just add them here
|
||||
if(entry.Depth == 0 && entry.Type ==.Bofa)
|
||||
if (entry.Depth == 0 && entry.Type == .Bofa)
|
||||
{
|
||||
if(!pResult.ContainsKey(entry.Data.Bofa.Name))
|
||||
if (!pResult.ContainsKey(entry.Data.Bofa.Name))
|
||||
{
|
||||
last = entry.Data.Bofa;
|
||||
pResult.Add(entry.Data.Bofa.Name, entry.Data.Bofa);
|
||||
|
@ -67,27 +68,27 @@ class BofaParser
|
|||
delete entry.Data.Bofa;
|
||||
}
|
||||
}
|
||||
else if(entry.Depth == 1 && entry.Type == .Text)
|
||||
else if (entry.Depth == 1 && entry.Type == .Text)
|
||||
{
|
||||
if(last.Type == .Text)
|
||||
if (last.Type == .Text)
|
||||
last.Value.Text.Append(scope $"\n{entry.Data.Text}");
|
||||
else
|
||||
pErrors.Add(entry.Line); //Bad text error
|
||||
pErrors.Add(entry.Line); //Bad text error
|
||||
delete l;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.Depth--;
|
||||
if(last.[Friend]_Insert(&entry) case .Err)
|
||||
if (last.[Friend]_Insert(&entry) case .Err)
|
||||
{
|
||||
pErrors.Add(line);
|
||||
delete entry.Data.Bofa;
|
||||
}
|
||||
else if (entry.Type == .Text)
|
||||
delete l;
|
||||
}
|
||||
if(entry.Type == .Text)
|
||||
delete l;
|
||||
line++;
|
||||
}
|
||||
|
||||
return; //Being done normally
|
||||
}
|
||||
|
||||
|
@ -139,42 +140,41 @@ class BofaParser
|
|||
toReturn.Data.Text = line;
|
||||
toReturn.Depth = depth + 1;
|
||||
return toReturn;
|
||||
|
||||
}
|
||||
//We have now assured, that the object we are handling is seemingly a normal one
|
||||
StringView typeName;
|
||||
switch (type.0)
|
||||
{
|
||||
case "c":
|
||||
let tnameres = NextPart(line);
|
||||
if (tnameres.0 == "")
|
||||
{ //Its of type custom but ends after the custom
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
line = tnameres.1;
|
||||
typeName = tnameres.0;
|
||||
case "n":
|
||||
typeName = "Number";
|
||||
case "b":
|
||||
typeName = "Boolean";
|
||||
case "l":
|
||||
typeName = "Line";
|
||||
case "bn":
|
||||
typeName = "BigNumber";
|
||||
case "i":
|
||||
typeName = "Integer";
|
||||
case "bi":
|
||||
typeName = "BigInteger";
|
||||
case "t":
|
||||
typeName = "Text";
|
||||
case "a":
|
||||
typeName = "Array";
|
||||
case "o":
|
||||
typeName = "Object";
|
||||
default:
|
||||
case "c":
|
||||
let tnameres = NextPart(line);
|
||||
if (tnameres.0 == "")
|
||||
{ //Its of type custom but ends after the custom
|
||||
toReturn.Type = .Error;
|
||||
return toReturn; //Unsupported type error
|
||||
return toReturn;
|
||||
}
|
||||
line = tnameres.1;
|
||||
typeName = tnameres.0;
|
||||
case "n":
|
||||
typeName = "Number";
|
||||
case "b":
|
||||
typeName = "Boolean";
|
||||
case "l":
|
||||
typeName = "Line";
|
||||
case "bn":
|
||||
typeName = "BigNumber";
|
||||
case "i":
|
||||
typeName = "Integer";
|
||||
case "bi":
|
||||
typeName = "BigInteger";
|
||||
case "t":
|
||||
typeName = "Text";
|
||||
case "a":
|
||||
typeName = "Array";
|
||||
case "o":
|
||||
typeName = "Object";
|
||||
default:
|
||||
toReturn.Type = .Error;
|
||||
return toReturn; //Unsupported type error
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -215,77 +215,77 @@ class BofaParser
|
|||
{
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
Bofa bofaRes = new .();
|
||||
bofaRes.Name = nameres.0;
|
||||
bofaRes.Typename = typeName;
|
||||
switch (type.0)
|
||||
{
|
||||
case "n":
|
||||
bofaRes.Type = .Number;
|
||||
var result = float.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.Number = result.Value;
|
||||
case "b":
|
||||
if (line == "true")
|
||||
bofaRes.Value.Boolean = true;
|
||||
else if (line == "false")
|
||||
bofaRes.Value.Boolean = false;
|
||||
else
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Type = .Boolean;
|
||||
case "l":
|
||||
bofaRes.Value.Line = line;
|
||||
bofaRes.Type = .Line;
|
||||
case "bn":
|
||||
bofaRes.Type = .BigNumber;
|
||||
var result = double.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.BigNumber = result.Value;
|
||||
case "i":
|
||||
bofaRes.Type = .Integer;
|
||||
var result = int32.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.Integer = result.Value;
|
||||
case "bi":
|
||||
bofaRes.Type = .BigInteger;
|
||||
var result = int64.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.BigInteger = result.Value;
|
||||
case "t":
|
||||
bofaRes.Value.Text = new String(line);
|
||||
bofaRes.Type = .Text;
|
||||
case "c":
|
||||
bofaRes.Value.Custom = line;
|
||||
bofaRes.Type = .Custom;
|
||||
default: //Unknown type
|
||||
case "n":
|
||||
bofaRes.Type = .Number;
|
||||
var result = float.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.Number = result.Value;
|
||||
case "b":
|
||||
if (line == "true")
|
||||
bofaRes.Value.Boolean = true;
|
||||
else if (line == "false")
|
||||
bofaRes.Value.Boolean = false;
|
||||
else
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Type = .Boolean;
|
||||
case "l":
|
||||
bofaRes.Value.Line = line;
|
||||
bofaRes.Type = .Line;
|
||||
case "bn":
|
||||
bofaRes.Type = .BigNumber;
|
||||
var result = double.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.BigNumber = result.Value;
|
||||
case "i":
|
||||
bofaRes.Type = .Integer;
|
||||
var result = int32.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.Integer = result.Value;
|
||||
case "bi":
|
||||
bofaRes.Type = .BigInteger;
|
||||
var result = int64.Parse(line);
|
||||
if (result case .Err)
|
||||
{
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
bofaRes.Value.BigInteger = result.Value;
|
||||
case "t":
|
||||
bofaRes.Value.Text = new String(line);
|
||||
bofaRes.Type = .Text;
|
||||
case "c":
|
||||
bofaRes.Value.Custom = line;
|
||||
bofaRes.Type = .Custom;
|
||||
default: //Unknown type
|
||||
delete bofaRes;
|
||||
toReturn.Type = .Error;
|
||||
return toReturn;
|
||||
}
|
||||
#endregion
|
||||
//If this ever returns something went wrong
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
using Bofa.Serialization;
|
||||
|
||||
namespace System
|
||||
{
|
||||
static
|
||||
|
@ -7,4 +9,23 @@ namespace System
|
|||
*(T*)(void*)&v
|
||||
}
|
||||
}
|
||||
|
||||
extension Int : IBofaParseable
|
||||
{
|
||||
public bool Serialize(Bofa.Bofa pTarget)
|
||||
{
|
||||
pTarget.Type = .Integer;
|
||||
pTarget.Typename = "Integer";
|
||||
pTarget.Value.Integer = (.)this;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Deserialize(Bofa.Bofa pInput) mut
|
||||
{
|
||||
if(pInput.Type != .Integer)
|
||||
return false;
|
||||
this = (.)pInput.Value.Integer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
20
src/Program.bf
Normal file
20
src/Program.bf
Normal file
|
@ -0,0 +1,20 @@
|
|||
namespace Bofa;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
class Program
|
||||
{
|
||||
|
||||
public static void Main()
|
||||
{
|
||||
|
||||
Bofa.Testing.Profiling.Profiling_Depth_Testing();
|
||||
Bofa.Testing.Profiling.Profiling_Depth_Testing_Medium();
|
||||
Bofa.Testing.Profiling.Profiling_Normal();
|
||||
Bofa.Testing.Profiling.Profiling_Normal_Medium();
|
||||
Bofa.Testing.Profiling.Profiling_Normal_Large();
|
||||
Bofa.Testing.Profiling.Profiling_Texts();
|
||||
Bofa.Testing.Profiling.Profiling_Texts_Large();
|
||||
}
|
||||
}
|
13
src/Serialization/BofaIncludeAttribute.bf
Normal file
13
src/Serialization/BofaIncludeAttribute.bf
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace Bofa.Serialization;
|
||||
|
||||
using System;
|
||||
|
||||
struct BofaIncludeAttribute : Attribute
|
||||
{
|
||||
public StringView Name;
|
||||
|
||||
public this(StringView pName)
|
||||
{
|
||||
Name = pName;
|
||||
}
|
||||
}
|
112
src/Serialization/BofaSerializeAttribute.bf
Normal file
112
src/Serialization/BofaSerializeAttribute.bf
Normal file
|
@ -0,0 +1,112 @@
|
|||
namespace Bofa.Serialization;
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using Bofa;
|
||||
|
||||
[AttributeUsage(.Struct | .Class)]
|
||||
struct BofaSerializeAttribute : Attribute, IOnTypeInit
|
||||
{
|
||||
[Comptime]
|
||||
public void OnTypeInit(Type type, Self* prev)
|
||||
{
|
||||
String serializeString = scope .("public bool Serialize(Bofa b)\n{\n");
|
||||
String deserializeString = scope .("public bool Deserialize(Bofa b)\n{\n");
|
||||
|
||||
serializeString.Append("""
|
||||
b.Type = .Object;
|
||||
b.Value.Object = new .();
|
||||
b.Typename = "Object";
|
||||
Bofa toAdd;
|
||||
|
||||
""");
|
||||
|
||||
deserializeString.Append("""
|
||||
if(b.Type != .Object)
|
||||
return false;
|
||||
|
||||
""");
|
||||
|
||||
|
||||
var fields = type.GetFields();
|
||||
for(var f in fields)
|
||||
{
|
||||
if(!f.IsPublic && !f.HasCustomAttribute<BofaIncludeAttribute>())
|
||||
continue;
|
||||
|
||||
bool hasIFace = false;
|
||||
for(var i in f.FieldType.Interfaces)
|
||||
if(i == typeof(IBofaParseable))
|
||||
hasIFace = true;
|
||||
|
||||
//Hardcoded stuff
|
||||
if(f.FieldType == typeof(int))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(int8))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(int16))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(int32))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(int64))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(uint))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(uint8))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(uint16))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(uint32))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(uint64))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(char8))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(char16))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(char32))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(float))
|
||||
hasIFace = true;
|
||||
else if(f.FieldType == typeof(double))
|
||||
hasIFace = true;
|
||||
|
||||
if(!hasIFace)
|
||||
continue;
|
||||
|
||||
|
||||
StringView name;
|
||||
name = f.Name;
|
||||
if(f.HasCustomAttribute<BofaIncludeAttribute>() && f.GetCustomAttribute<BofaIncludeAttribute>() case .Ok(let attr))
|
||||
name = attr.Name;
|
||||
|
||||
serializeString.Append(scope $"""
|
||||
toAdd = new .();
|
||||
toAdd.Name = "{name}";
|
||||
if(!{f.Name}.Serialize(toAdd))
|
||||
\{
|
||||
delete toAdd;
|
||||
return false;
|
||||
\}
|
||||
else
|
||||
b.Value.Object.Add("{name}", toAdd);
|
||||
""");
|
||||
|
||||
deserializeString.Append(scope $"""
|
||||
if(!b.Value.Object.ContainsKey("{name}"))
|
||||
return false;
|
||||
if(!{f.Name}.Deserialize(b.Value.Object["{name}"]))
|
||||
return false;
|
||||
""");
|
||||
|
||||
}
|
||||
|
||||
|
||||
serializeString.Append("\n\treturn true;\n}\n");
|
||||
deserializeString.Append("\n\treturn true;\n}\n");
|
||||
Compiler.EmitTypeBody(type, serializeString);
|
||||
Compiler.EmitTypeBody(type, deserializeString);
|
||||
Compiler.EmitAddInterface(type, typeof(IBofaParseable));
|
||||
}
|
||||
}
|
11
src/Serialization/IBofaParseable.bf
Normal file
11
src/Serialization/IBofaParseable.bf
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Bofa.Serialization;
|
||||
|
||||
using System;
|
||||
|
||||
interface IBofaParseable
|
||||
{
|
||||
///Serializes the current state of a bofa object, may allocate subobjects to fill
|
||||
public bool Serialize(Bofa pTarget) mut;
|
||||
///Attempt to restore an object from the bofa input state
|
||||
public bool Deserialize(Bofa pInput) mut;
|
||||
}
|
|
@ -7,7 +7,7 @@ using System.Collections;
|
|||
|
||||
class Fuzzing
|
||||
{
|
||||
[Test(Name = "Fuzzing - 10 * 1000000 random characters")]
|
||||
//[Test(Name = "Fuzzing - 10 * 1000000 random characters")]
|
||||
public static void Fuzzin_Random()
|
||||
{
|
||||
for (int i < 10)
|
||||
|
@ -25,7 +25,7 @@ class Fuzzing
|
|||
}
|
||||
}
|
||||
|
||||
[Test(Name = "Fuzzing - 10 * 10000000 random characters")]
|
||||
//[Test(Name = "Fuzzing - 10 * 10000000 random characters")]
|
||||
public static void Fuzzin_Random_Large()
|
||||
{
|
||||
for (int i < 10)
|
||||
|
|
25
src/Testing/Serialization.bf
Normal file
25
src/Testing/Serialization.bf
Normal file
|
@ -0,0 +1,25 @@
|
|||
namespace Bofa.Testing;
|
||||
|
||||
using System;
|
||||
|
||||
using Bofa;
|
||||
using Bofa.Serialization;
|
||||
|
||||
[BofaSerialize]
|
||||
class Serialization
|
||||
{
|
||||
public int anInteger = (.)1;
|
||||
|
||||
[Test]
|
||||
public static void Test()
|
||||
{
|
||||
Serialization s = scope .();
|
||||
Bofa b = scope .();
|
||||
b.Name = "s";
|
||||
s.Serialize(b);
|
||||
|
||||
Console.WriteLine(b.ToString(.. scope .()));
|
||||
//Console.Read();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue