Rewrite #2
13 changed files with 11 additions and 904 deletions
|
@ -1,13 +0,0 @@
|
|||
namespace Bofa;
|
||||
|
||||
using System;
|
||||
|
||||
struct BofaAbleAttribute : Attribute
|
||||
{
|
||||
public StringView Name;
|
||||
|
||||
public this(StringView pName)
|
||||
{
|
||||
Name = pName;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
namespace Bofa;
|
||||
|
||||
using System;
|
||||
|
||||
[AttributeUsage(.Field)]
|
||||
struct BofaObjectAttribute : Attribute, IOnTypeInit
|
||||
{
|
||||
public StringView Name;
|
||||
|
||||
public this(StringView pName)
|
||||
{
|
||||
Name = pName;
|
||||
}
|
||||
|
||||
[Comptime]
|
||||
public void OnTypeInit(Type type, Self* prev)
|
||||
{
|
||||
Compiler.EmitTypeBody(type, "public override void ToString(String str)\n{\n");
|
||||
for (var fieldInfo in type.GetFields())
|
||||
{
|
||||
if (!fieldInfo.IsInstanceField)
|
||||
continue;
|
||||
if (@fieldInfo.Index > 0)
|
||||
Compiler.EmitTypeBody(type, "\tstr.Append(\", \");\n");
|
||||
Compiler.EmitTypeBody(type, scope $"\tstr.AppendF($\"{fieldInfo.Name}={{ {fieldInfo.Name} }}\");\n");
|
||||
}
|
||||
Compiler.EmitTypeBody(type, "}");
|
||||
}
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
namespace Bofa.Builder;
|
||||
using System;
|
||||
using System.Collections;
|
||||
typealias bb = BofaBuilder;
|
||||
class BofaBuilder
|
||||
{
|
||||
/*
|
||||
Allows users to easily build a bofa file via code
|
||||
name, typename, typeindicator, value
|
||||
|
||||
This is really fucking slow, because we are allocating so much
|
||||
In a sensible application you wouldnd call this all that much anyways, so I dont care
|
||||
*/
|
||||
public struct b
|
||||
{
|
||||
public String Name; //This is always dynamic
|
||||
public String Type; //Never dynamic
|
||||
public String TypeName; //Only dynamic on custom types
|
||||
public String Value; //Dynamic on everything that isnt a array or object
|
||||
public Span<b> Members;
|
||||
|
||||
public this(String name, String type, String typeName, String value, Span<b> members)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
TypeName = typeName;
|
||||
Value = value;
|
||||
Members = members;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
delete Name;
|
||||
if(Type == "c")
|
||||
delete TypeName;
|
||||
|
||||
if(Type != "a" && Type != "o")
|
||||
delete Value;
|
||||
|
||||
for(let e in Members)
|
||||
{
|
||||
e.Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void ToString(String toAppend, uint32 depth)
|
||||
{
|
||||
String toAdd = scope .(scope $"{Type} ");
|
||||
toAdd.PadLeft(depth+toAdd.Length,' ');
|
||||
if(Type == "c")
|
||||
toAdd.Append(scope $"{TypeName} ");
|
||||
toAdd.Append(scope $"{Name} ");
|
||||
//Every single
|
||||
if(Type != "a" && Type != "o") //In this case we can just normally return
|
||||
{
|
||||
|
||||
if(Type != "t")
|
||||
toAdd.Append(scope $"{Value}");
|
||||
else
|
||||
{
|
||||
var en = Value.Split('\n');
|
||||
toAdd.Append(en.GetNext());
|
||||
|
||||
for(var e in en)
|
||||
{
|
||||
toAdd.Append('\n');
|
||||
String n = scope .();
|
||||
n.PadLeft(depth+1, ' ');
|
||||
n.Append("- ");
|
||||
n.Append(e);
|
||||
toAdd.Append(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
toAdd.Append('\n');
|
||||
if(Type == "a" || Type == "o")
|
||||
{
|
||||
for(var b in Members)
|
||||
{
|
||||
b.ToString(toAdd,depth+1);
|
||||
}
|
||||
}
|
||||
toAppend.Append(toAdd);
|
||||
}
|
||||
}
|
||||
|
||||
private Span<b> values;
|
||||
private List<b> valueList = new .();
|
||||
public this(params Span<b> input)
|
||||
{
|
||||
values = input;
|
||||
}
|
||||
|
||||
|
||||
public ~this()
|
||||
{
|
||||
for(var a in values)
|
||||
a.Cleanup();
|
||||
|
||||
for(var a in valueList)
|
||||
a.Cleanup();
|
||||
delete valueList;
|
||||
}
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
for(var a in values)
|
||||
{
|
||||
a.ToString(strBuffer, 0);
|
||||
}
|
||||
for(var a in valueList)
|
||||
{
|
||||
a.ToString(strBuffer, 0);
|
||||
}
|
||||
if(strBuffer[strBuffer.Length-1] == '\n')
|
||||
strBuffer.RemoveFromEnd(1); //There are probably better ways to do this but I dont care
|
||||
}
|
||||
|
||||
///Adds a single entry after the creation
|
||||
public void Add(b pToAdd)
|
||||
{
|
||||
valueList.Add(pToAdd);
|
||||
}
|
||||
|
||||
public static b Num(StringView name, float number)
|
||||
{
|
||||
return .(new .(name), "n", null, new .(number.ToString(.. scope .())),null);
|
||||
}
|
||||
|
||||
public static b Bool(StringView name, bool bool)
|
||||
{
|
||||
return .(new .(name), "b", null, new .(bool.ToString(.. scope .())),null);
|
||||
}
|
||||
|
||||
public static b Line(StringView name, StringView line)
|
||||
{
|
||||
return .(new .(name), "l", null, new .(line),null);
|
||||
}
|
||||
|
||||
public static b BigNum(StringView name, double bigNum)
|
||||
{
|
||||
return .(new .(name), "bn", null, new .(bigNum.ToString(.. scope .())),null);
|
||||
}
|
||||
|
||||
public static b Int(StringView name, int32 number)
|
||||
{
|
||||
return .(new .(name), "i", null, new .(number.ToString(.. scope .())),null);
|
||||
}
|
||||
|
||||
public static b BigInt(StringView name, int64 number)
|
||||
{
|
||||
return .(new .(name), "bi", null, new .(number.ToString(.. scope .())),null);
|
||||
}
|
||||
|
||||
public static b Text(StringView name, StringView text)
|
||||
{
|
||||
return .(new .(name),"t", null, new .(text),null);
|
||||
}
|
||||
|
||||
public static b Custom(StringView name, StringView type, StringView value)
|
||||
{
|
||||
return .(new .(name), "c",new .(type), new .(value), null);
|
||||
}
|
||||
|
||||
public static b Object(StringView name, params Span<b> input)
|
||||
{
|
||||
return .(new .(name), "o", null,null,input);
|
||||
}
|
||||
|
||||
public static b Array(StringView name, params Span<b> input)
|
||||
{
|
||||
return .(new .(name), "a", null,new .(""),input);
|
||||
}
|
||||
|
||||
|
||||
//Array functions, that dont take a name
|
||||
public static b NumA(float value)
|
||||
{
|
||||
return Num("-", value);
|
||||
}
|
||||
public static b BoolA(bool value)
|
||||
{
|
||||
return Bool("-", value);
|
||||
}
|
||||
public static b LineA(StringView value)
|
||||
{
|
||||
return Line("-", value);
|
||||
}
|
||||
public static b BigNumA(double value)
|
||||
{
|
||||
return BigNum("-", value);
|
||||
}
|
||||
public static b IntA(int32 value)
|
||||
{
|
||||
return Int("-", value);
|
||||
}
|
||||
public static b BigIntA(int64 value)
|
||||
{
|
||||
return BigInt("-", value);
|
||||
}
|
||||
public static b TextA(StringView value)
|
||||
{
|
||||
return Text("-", value);
|
||||
}
|
||||
public static b CustomA(StringView type, StringView value)
|
||||
{
|
||||
return Custom("-", type, value);
|
||||
}
|
||||
public static b ObjectA(params Span<b> input)
|
||||
{
|
||||
return .("-", "o", null, null, input);
|
||||
}
|
||||
public static b ArrayA(params Span<b> input)
|
||||
{
|
||||
return .("-", "a", null, null, input);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void Test()
|
||||
{
|
||||
BofaBuilder builder = scope .(
|
||||
bb.Num("Number",123),
|
||||
bb.Custom("farbe", "color", "255 0 255"),
|
||||
bb.Text("Text", "multi \nLine"),
|
||||
bb.Object( "obj",
|
||||
bb.Num("SubObject", 123)
|
||||
)
|
||||
);
|
||||
Console.WriteLine(builder.ToString(.. scope .()));
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
namespace Bofa;
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
class BofaReflector
|
||||
{
|
||||
|
||||
///Parse an object into its bofa representation
|
||||
public static void ToBofa<T>(T pInput, Bofa buffer)
|
||||
{
|
||||
/*
|
||||
Recursivly loop through all fields of the object and parse all marked fields
|
||||
if a custom parser is supplied via IBofaParseable we use that.
|
||||
*/
|
||||
|
||||
//User supplied their own parser
|
||||
if(let iface = pInput as IBofaParseable)
|
||||
{
|
||||
//Simply just call the user supplied parser
|
||||
iface.ToBofa(buffer);
|
||||
}
|
||||
|
||||
buffer.Type = .Object;
|
||||
buffer.TypeName = "Object";
|
||||
buffer.Value.Object = new .();
|
||||
|
||||
var fields = typeof(T).GetFields();
|
||||
for(var i in fields) //Loop through all fields of the object
|
||||
{
|
||||
//If we should actually parse the field
|
||||
if(i.GetCustomAttribute<BofaAbleAttribute>() case .Ok(let attr))
|
||||
{
|
||||
if(i.GetValue(pInput) case .Ok(let value))
|
||||
{
|
||||
|
||||
Bofa fieldContent = new .();
|
||||
fieldContent.Name = attr.Name;
|
||||
Compiler.Mixin(scope $"ToBofa<{i.GetType()}>(value,fieldContent);");
|
||||
//ToBofa<typeof(value)>(value, fieldContent);
|
||||
buffer.Value.Object.Add(fieldContent.Name, fieldContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
namespace Bofa;
|
||||
using System;
|
||||
using System.Collections;
|
||||
class BofaResult
|
||||
{
|
||||
/*
|
||||
BofaResult contains the result of an interaction with the Bofa Parser Library
|
||||
If you parse a String the parser will return a BofaResult Object
|
||||
Querying an existing Bofa Result will also return a sub BofaResult
|
||||
This exist in order to keep the bofa data objects clean and instead manage access via this class
|
||||
It also contains information about wether any one query was sucessfull
|
||||
*/
|
||||
private bool _isResult = false; //If this is true we dont delete any actual object data
|
||||
private String _data = null; //The backing data, needs to be cleared on destruction if set
|
||||
private Dictionary<StringView, Bofa> _contents = new Dictionary<StringView, Bofa>(10); //Storage
|
||||
private List<Bofa> _result = null;
|
||||
private Bofa _lastObject = null; //Keeps track of the last object we have added
|
||||
|
||||
|
||||
public bool OK { //Keeps track of wether the parsing failed at some point
|
||||
public get;
|
||||
private set;
|
||||
} = true;
|
||||
|
||||
public ~this()
|
||||
{
|
||||
|
||||
if(_result != null)
|
||||
delete _result;
|
||||
|
||||
if(_data != null)
|
||||
{
|
||||
delete _data;
|
||||
for(let i in _contents)
|
||||
{
|
||||
delete i.value;
|
||||
}
|
||||
} //We only delete values on the core object in order to not have error with dumb shit
|
||||
|
||||
delete _contents;
|
||||
}
|
||||
|
||||
private bool Insert(BofaParser.lineParserResult pResult)
|
||||
{ //This is guaranteed to be a valid pResult, because no one would ever call this from somewhere else with different params
|
||||
//DONT DO THIS ^
|
||||
|
||||
if(pResult.Bofa.0 > 0 && (_lastObject == null || (_lastObject.Type != .Object && _lastObject.Type != .Array && _lastObject.Type != .Text)))
|
||||
return false;
|
||||
|
||||
if(pResult.Bofa.0 > 0)
|
||||
if(pResult.IsBofa)
|
||||
return _lastObject.[Friend]Insert(pResult.Bofa.0-1, pResult.Bofa.1);
|
||||
else
|
||||
return _lastObject.[Friend]Insert(pResult.Text.0-1, null, pResult.Text.1);
|
||||
//Okay so we really need to add it in on this layer
|
||||
|
||||
if(!pResult.IsBofa)
|
||||
{ //For text entries on the current layer
|
||||
if(_lastObject.Type != .Text)
|
||||
return false;
|
||||
_lastObject.Value.Text.Append(scope $"\n{pResult.Text.1}");
|
||||
return true;
|
||||
}
|
||||
|
||||
let toAdd = pResult.Bofa.1;
|
||||
if(_contents.ContainsKey(toAdd.Name))
|
||||
return false; //Dublicate name error
|
||||
_contents.Add(toAdd.Name, toAdd);
|
||||
_lastObject = toAdd;
|
||||
return true;
|
||||
}
|
||||
|
||||
///Interface functions go here
|
||||
public Result<Bofa> this[StringView pValue]
|
||||
{
|
||||
public get {
|
||||
if(!_contents.ContainsKey(pValue))
|
||||
return .Err;
|
||||
return _contents[pValue];
|
||||
}
|
||||
}
|
||||
|
||||
public Result<Bofa> GetByName(StringView pValue)
|
||||
{
|
||||
return this[pValue];
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
namespace Bofa;
|
||||
using System;
|
||||
using System.Collections;
|
||||
[Union]
|
||||
struct BofaValue
|
||||
{
|
||||
public float Number;
|
||||
public double BigNumber;
|
||||
public int32 Integer;
|
||||
public int64 BigInteger;
|
||||
public bool Boolean;
|
||||
public StringView Line;
|
||||
public StringView Custom;
|
||||
public String Text;
|
||||
public Dictionary<StringView, Bofa> Object = null;
|
||||
public List<Bofa> Array = null;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
namespace Bofa;
|
||||
|
||||
interface IBofaParseable
|
||||
{
|
||||
public void ToBofa(Bofa target);
|
||||
public void FromBofa(Bofa input);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
namespace Bofa.Testing.Parsing;
|
||||
|
||||
class T_Bofa
|
||||
{
|
||||
//TODO: Add some testcases that cover multiple lines and insertions
|
||||
//Such as texts, objects and arrays
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
namespace Bofa.Testing.Parsing;
|
||||
|
||||
class T_BofaError
|
||||
{
|
||||
//TODO; add some testcases that fail the parser
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
namespace Bofa.Testing.Parsing;
|
||||
using System;
|
||||
using Bofa;
|
||||
using Bofa.Builder;
|
||||
class T_SingleLine
|
||||
{
|
||||
/*
|
||||
This class checks the validity of any single line bofa object
|
||||
*/
|
||||
|
||||
[Test] //Any line that should be parsed as empty
|
||||
public static void EmptyLine()
|
||||
{
|
||||
StringView[] lineArr = scope .(
|
||||
"",
|
||||
" ",
|
||||
"\t",
|
||||
" ",
|
||||
"#asdasdasdasd",
|
||||
" # asdasdasdasd",
|
||||
"#"
|
||||
);
|
||||
|
||||
BofaParser p = .();
|
||||
for(let e in lineArr)
|
||||
{
|
||||
var r = p.[Friend]parseLine(e);
|
||||
if(!r.IsEmpty)
|
||||
Runtime.FatalError();
|
||||
}
|
||||
}
|
||||
|
||||
[Test] //Some lines that should be parsed as text
|
||||
public static void Text()
|
||||
{
|
||||
StringView[] lineArr = scope .(
|
||||
"- text", //Depth 0
|
||||
" - text", //Depth 1
|
||||
" - TEasdasdas iodfjoidfiosduiofsd", //Depth 2
|
||||
" - dadsadasdasdasfjrdfiofjiofdsghjniodfgdf" //Depth 3
|
||||
);
|
||||
BofaParser p = .();
|
||||
for(int i < lineArr.Count)
|
||||
{
|
||||
var r = p.[Friend]parseLine(lineArr[i]);
|
||||
if(!r.Ok || r.IsEmpty)
|
||||
Runtime.FatalError();
|
||||
|
||||
if(r.Text.0 != i+1)
|
||||
Runtime.FatalError();
|
||||
}
|
||||
}
|
||||
|
||||
[Test] //Doing some parsing
|
||||
public static void Parse()
|
||||
{
|
||||
StringView[] lineArr = scope .(
|
||||
"n float 1223",
|
||||
"n float 1.232",
|
||||
"b bool true",
|
||||
"b bool false",
|
||||
"l line text goes here",
|
||||
"bn BigNumber 3242343242354543",
|
||||
"i integer 12423423",
|
||||
"bi BigInteger 344234323454365",
|
||||
"t text sdfsdgdfgdfgdf",
|
||||
"t text ",
|
||||
"c color redd 255 0 0",
|
||||
"a array",
|
||||
"o object"
|
||||
);
|
||||
BofaParser p = .();
|
||||
for(var e in lineArr)
|
||||
{
|
||||
var r = p.[Friend]parseLine(e);
|
||||
if(!r.Ok || r.IsEmpty || !r.IsBofa)
|
||||
Runtime.FatalError();
|
||||
delete r.Bofa.1;
|
||||
}
|
||||
}
|
||||
}
|
78
src/bofa.bf
78
src/bofa.bf
|
@ -1,78 +0,0 @@
|
|||
namespace Bofa;
|
||||
using System;
|
||||
class Bofa
|
||||
{
|
||||
public eBofaType Type;
|
||||
public StringView TypeName;
|
||||
public StringView Name;
|
||||
public BofaValue Value;
|
||||
|
||||
private Bofa LastObject = null;
|
||||
|
||||
public ~this()
|
||||
{
|
||||
|
||||
if(Type == .Text)
|
||||
delete Value.Text;
|
||||
else if(Type == .Object && Value.Object != null)
|
||||
DeleteDictionaryAndValues!(Value.Object);
|
||||
else if(Type == .Array && Value.Array != null)
|
||||
DeleteContainerAndItems!(Value.Array);
|
||||
}
|
||||
|
||||
private bool Insert(uint32 depth, Bofa toInsert, StringView toAdd = "")
|
||||
{
|
||||
if(depth > 0 && (LastObject == null || (LastObject.Type != .Array && LastObject.Type != .Object && LastObject.Type != .Text)))
|
||||
return false;
|
||||
|
||||
if(depth > 0)
|
||||
{
|
||||
return LastObject.Insert(depth-1, toInsert, toAdd);
|
||||
}
|
||||
//Actually insert it now
|
||||
switch(Type)
|
||||
{
|
||||
case .Text:
|
||||
Value.Text.Append(scope $"\n{toAdd}");
|
||||
case .Array:
|
||||
Value.Array.Add(toInsert);
|
||||
case .Object:
|
||||
if(Value.Object.ContainsKey(toInsert.Name))
|
||||
return false; //Error
|
||||
Value.Object.Add(toInsert.Name, toInsert);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
LastObject = toInsert;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//Finding specific entries easier
|
||||
public Result<Bofa> this[StringView name]
|
||||
{
|
||||
public get {
|
||||
if(Type != .Object)
|
||||
return .Err;
|
||||
if(!Value.Object.ContainsKey(name))
|
||||
return .Err;
|
||||
return .Ok(Value.Object[name]);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<Bofa> this[uint32 number]
|
||||
{
|
||||
public get {
|
||||
if(Type != .Array)
|
||||
return .Err;
|
||||
if(Value.Array.Count <= number)
|
||||
return .Err;
|
||||
return Value.Array[number];
|
||||
}
|
||||
}
|
||||
|
||||
public static mixin GetValueOrDefault<T>(Result<T> result, T dfault)
|
||||
{
|
||||
result case .Err ? dfault : result
|
||||
}
|
||||
}
|
|
@ -1,287 +0,0 @@
|
|||
namespace Bofa;
|
||||
using System;
|
||||
struct BofaParser
|
||||
{
|
||||
public BofaResult Parse(StringView pLine)
|
||||
{
|
||||
BofaResult toReturn = new .();
|
||||
toReturn.[Friend]_data = new String(pLine);
|
||||
var enumerator = toReturn.[Friend]_data.Split('\n');
|
||||
for(let e in enumerator)
|
||||
{ //Loop through each line
|
||||
var res = parseLine(e); //Handle the result and do the inserting
|
||||
if(res.IsEmpty)
|
||||
continue;
|
||||
if(!res.Ok)
|
||||
{
|
||||
toReturn.[Friend]OK = false;
|
||||
return toReturn;
|
||||
}
|
||||
var result = toReturn.[Friend]Insert(res);
|
||||
if(result == false)
|
||||
{
|
||||
toReturn.[Friend]OK = false;
|
||||
if(res.IsBofa)
|
||||
delete res.Bofa.1;
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
///Atttempts to parse a single line into a bofa object and returns its depth
|
||||
private lineParserResult parseLine(StringView pLine)
|
||||
{
|
||||
StringView line = pLine; //So that we can work on it
|
||||
|
||||
#region Depth
|
||||
//Get the depth of the line
|
||||
uint32 depth = 0;
|
||||
var hasContent = false; //In order to check wether it just ran out, or wether we actually have content
|
||||
for(var c in line)
|
||||
{
|
||||
if(c == ' ' || c == ' ')
|
||||
{
|
||||
depth++;
|
||||
continue;
|
||||
}
|
||||
else if(c == '#')
|
||||
return .(); //Comment
|
||||
hasContent = true;
|
||||
break;
|
||||
}
|
||||
if(!hasContent)
|
||||
return .(); //Is empty
|
||||
line = .(line, depth);
|
||||
#endregion
|
||||
|
||||
#region Type
|
||||
//Get the type of the line
|
||||
let type = NextPart(line);
|
||||
line = type.1;
|
||||
if(type.0 == "") //Shouldnt be empty
|
||||
return .();
|
||||
else if(type.0 == "-")
|
||||
return .(type.1, depth+1);
|
||||
//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 == "")
|
||||
return .(false);
|
||||
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:
|
||||
return .(false); //Unsupported type error
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Name
|
||||
//Get the name and return if its a array or object
|
||||
let nameres = NextPart(line);
|
||||
line = nameres.1;
|
||||
if(nameres.0 == "")
|
||||
return .(false);
|
||||
|
||||
if(type.0 == "o" || type.0 == "a")
|
||||
{
|
||||
Bofa toReturn = new Bofa();
|
||||
toReturn.Name = nameres.0;
|
||||
toReturn.TypeName = typeName;
|
||||
if(type.0 == "o")
|
||||
{
|
||||
toReturn.Type = .Object;
|
||||
toReturn.Value.Object = new .();
|
||||
return .(toReturn, depth);
|
||||
}
|
||||
toReturn.Type = .Array;
|
||||
toReturn.Value.Array = new .();
|
||||
return .(toReturn, depth);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Value
|
||||
if(line == "")
|
||||
return .(false);
|
||||
Bofa toReturn = new .();
|
||||
toReturn.Name = nameres.0;
|
||||
toReturn.TypeName = typeName;
|
||||
switch(type.0)
|
||||
{
|
||||
case "n":
|
||||
toReturn.Type = .Number;
|
||||
var result = float.Parse(line);
|
||||
if(result case .Err)
|
||||
{
|
||||
delete toReturn;
|
||||
return .(false);
|
||||
}
|
||||
toReturn.Value.Number = result.Value;
|
||||
case "b":
|
||||
if(line == "true")
|
||||
toReturn.Value.Boolean = true;
|
||||
else if(line == "false")
|
||||
toReturn.Value.Boolean = false;
|
||||
else
|
||||
{
|
||||
delete toReturn;
|
||||
return .(false);
|
||||
}
|
||||
toReturn.Type = .Boolean;
|
||||
case "l":
|
||||
toReturn.Value.Line = line;
|
||||
toReturn.Type = .Line;
|
||||
case "bn":
|
||||
toReturn.Type = .BigNumber;
|
||||
var result = double.Parse(line);
|
||||
if(result case .Err)
|
||||
{
|
||||
delete toReturn;
|
||||
return .(false);
|
||||
}
|
||||
toReturn.Value.BigNumber = result.Value;
|
||||
case "i":
|
||||
toReturn.Type = .Integer;
|
||||
var result = int32.Parse(line);
|
||||
if(result case .Err)
|
||||
{
|
||||
delete toReturn;
|
||||
return .(false);
|
||||
}
|
||||
toReturn.Value.Integer = result.Value;
|
||||
case "bi":
|
||||
toReturn.Type = .BigInteger;
|
||||
var result = int64.Parse(line);
|
||||
if(result case .Err)
|
||||
{
|
||||
delete toReturn;
|
||||
return .(false);
|
||||
}
|
||||
toReturn.Value.BigInteger = result.Value;
|
||||
case "t":
|
||||
toReturn.Value.Text = new .(line);
|
||||
toReturn.Type = .Text;
|
||||
case "c":
|
||||
toReturn.Value.Custom = line;
|
||||
toReturn.Type = .Custom;
|
||||
default:
|
||||
delete toReturn;
|
||||
return .(false);
|
||||
}
|
||||
#endregion
|
||||
//If this ever returns something went wrong
|
||||
return .(toReturn,depth);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static (StringView, StringView) NextPart(StringView pLine)
|
||||
{
|
||||
int i = 0;
|
||||
for(var c in pLine)
|
||||
{
|
||||
if(c == ' ')
|
||||
{
|
||||
if(@c.GetNext() case .Ok(let val))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (.(pLine, 0, (i < pLine.Length) ? i-1 : i), .(pLine, i));
|
||||
}
|
||||
|
||||
public struct lineParserResult
|
||||
{ //I hate that this is necessary to handle parseLine, but its just so much data that needs to be moved
|
||||
private bool ok = true;
|
||||
private bool isEmpty = false;
|
||||
private uint32 depth = 0;
|
||||
|
||||
private bool isBofa = true; //Wether this is a bofa or a string extension
|
||||
private StringView text = "";
|
||||
private Bofa bofa = null;
|
||||
|
||||
public this(bool pIsEmpty = true)
|
||||
{ //Either for errors or incase its an empty line
|
||||
//the difference is that empty lines should be skipped, while an error would
|
||||
if(pIsEmpty)
|
||||
isEmpty = true;
|
||||
else
|
||||
ok = false;
|
||||
}
|
||||
|
||||
public this(StringView pText, uint32 pDepth = 0)
|
||||
{ //For text addendums
|
||||
depth = pDepth;
|
||||
isBofa = false;
|
||||
text = pText;
|
||||
}
|
||||
|
||||
public this(Bofa pBofa, uint32 pDepth = 0)
|
||||
{ //For normal bofa objects
|
||||
depth = pDepth;
|
||||
bofa = pBofa;
|
||||
}
|
||||
|
||||
public bool Ok
|
||||
{
|
||||
public get {
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
public get {
|
||||
return isEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsBofa
|
||||
{
|
||||
public get {
|
||||
return isBofa;
|
||||
}
|
||||
}
|
||||
|
||||
public (uint32, Bofa) Bofa
|
||||
{
|
||||
public get {
|
||||
return (depth, bofa);
|
||||
}
|
||||
}
|
||||
|
||||
public (uint32, StringView) Text
|
||||
{
|
||||
public get {
|
||||
return (depth, text);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
namespace Bofa;
|
||||
|
||||
enum eBofaType
|
||||
enum EBofaType
|
||||
{
|
||||
Number,
|
||||
Boolean,
|
||||
Line,
|
||||
BigNumber,
|
||||
Integer,
|
||||
BigInteger,
|
||||
Text,
|
||||
Custom,
|
||||
Array,
|
||||
Object
|
||||
Line, //String without \n
|
||||
Text, //String with \n
|
||||
Number, //32bit floating point number
|
||||
BigNumber, //64bit floating point number
|
||||
Integer, //32bit signed integer
|
||||
BigInteger, //64bit signed integer
|
||||
Boolean, //8bit true or false
|
||||
Object, // Key-Value container
|
||||
Array, //Numeric container
|
||||
Custom //String with a type attached to it
|
||||
}
|
Loading…
Add table
Reference in a new issue