From 8119e7a5ff9444fb12883da3e56caf3554c19a58 Mon Sep 17 00:00:00 2001 From: Piotr Fusik Date: Mon, 19 Feb 2024 15:55:02 +0100 Subject: [PATCH] [json] Python. #140 --- GenJs.fu | 1 - GenPy.fu | 51 +++++++++++++++++++++++++++++++++++++++++++ libfut.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++-- libfut.cs | 52 +++++++++++++++++++++++++++++++++++++++++++- libfut.js | 52 +++++++++++++++++++++++++++++++++++++++++++- test/JsonElement.fu | 2 +- 6 files changed, 205 insertions(+), 6 deletions(-) diff --git a/GenJs.fu b/GenJs.fu index bfb55420..17a823d5 100644 --- a/GenJs.fu +++ b/GenJs.fu @@ -1357,7 +1357,6 @@ public class GenJsNoModule : GenBase WriteLine("\treturn Array.isArray(e) ? JsonValueKind.ARRAY: e === null ? JsonValueKind.NULL : JsonValueKind.OBJECT;"); CloseBlock(); CloseBlock(); - WriteNewLine(); CloseBlock(); } if (this.StringWriter) { diff --git a/GenPy.fu b/GenPy.fu index 39f94ae7..de993b93 100644 --- a/GenPy.fu +++ b/GenPy.fu @@ -178,6 +178,7 @@ public class GenPy : GenPySwift case "global": case "import": case "is": + case "json": case "lambda": case "len": case "list": @@ -483,6 +484,9 @@ public class GenPy : GenPySwift case FuId.OrderedDictionaryCount: WriteStringLength(expr.Left); break; + case FuId.JsonElementValueKind: + WriteCall("JsonValueKind.get", expr.Left); + break; case FuId.MathNaN: Include("math"); Write("math.nan"); @@ -1060,6 +1064,18 @@ public class GenPy : GenPySwift case FuId.MatchGetCapture: WriteMethodCall(obj, "group", args[0]); break; + case FuId.JsonElementParse: + Include("json"); + obj.Accept(this, FuPriority.Assign); + WriteCall(" = json.loads", args[0]); + break; + case FuId.JsonElementGetObject: + case FuId.JsonElementGetArray: + case FuId.JsonElementGetString: + case FuId.JsonElementGetDouble: + case FuId.JsonElementGetBoolean: + obj.Accept(this, parent); + break; case FuId.MathMethod: case FuId.MathIsFinite: case FuId.MathIsNaN: @@ -1574,6 +1590,41 @@ public class GenPy : GenPySwift this.WrittenTypes.Clear(); this.SwitchBreak = false; OpenStringWriter(); + if (program.JsonValueKindEnum) { + WriteNewLine(); + Include("enum"); + Write("class JsonValueKind(enum.Enum)"); + OpenChild(); + WriteLine("OBJECT = 1"); + WriteLine("ARRAY = 2"); + WriteLine("STRING = 3"); + WriteLine("NUMBER = 4"); + WriteLine("TRUE = 5"); + WriteLine("FALSE = 6"); + WriteLine("NULL = 7"); + WriteLine("@staticmethod"); + Write("def get(e)"); + OpenChild(); + Write("match e"); + OpenChild(); + WriteLine("case dict():"); + WriteLine("\treturn JsonValueKind.OBJECT"); + WriteLine("case list():"); + WriteLine("\treturn JsonValueKind.ARRAY"); + WriteLine("case str():"); + WriteLine("\treturn JsonValueKind.STRING"); + WriteLine("case float():"); + WriteLine("\treturn JsonValueKind.NUMBER"); + WriteLine("case True:"); + WriteLine("\treturn JsonValueKind.TRUE"); + WriteLine("case False:"); + WriteLine("\treturn JsonValueKind.FALSE"); + WriteLine("case None:"); + WriteLine("\treturn JsonValueKind.NULL"); + CloseChild(); + CloseChild(); + CloseChild(); + } WriteTypes(program); CreateOutputFile(); WriteTopLevelNatives(program); diff --git a/libfut.cpp b/libfut.cpp index 6c4719a0..c0a8c439 100644 --- a/libfut.cpp +++ b/libfut.cpp @@ -19882,7 +19882,6 @@ void GenJsNoModule::writeLib(const FuProgram * program) writeLine("\treturn Array.isArray(e) ? JsonValueKind.ARRAY: e === null ? JsonValueKind.NULL : JsonValueKind.OBJECT;"); closeBlock(); closeBlock(); - writeNewLine(); closeBlock(); } if (this->stringWriter) { @@ -22423,7 +22422,7 @@ void GenPy::writeNameNotKeyword(std::string_view name) { if (name == "this") write("self"); - else if (name == "And" || name == "Array" || name == "As" || name == "Assert" || name == "Async" || name == "Await" || name == "Bool" || name == "Break" || name == "Class" || name == "Continue" || name == "Def" || name == "Del" || name == "Dict" || name == "Elif" || name == "Else" || name == "Enum" || name == "Except" || name == "Finally" || name == "For" || name == "From" || name == "Global" || name == "If" || name == "Import" || name == "In" || name == "Is" || name == "Lambda" || name == "Len" || name == "List" || name == "Math" || name == "Nonlocal" || name == "Not" || name == "Or" || name == "Pass" || name == "Pyfma" || name == "Raise" || name == "Re" || name == "Return" || name == "Str" || name == "Sys" || name == "Try" || name == "While" || name == "With" || name == "Yield" || name == "and" || name == "array" || name == "as" || name == "async" || name == "await" || name == "def" || name == "del" || name == "dict" || name == "elif" || name == "enum" || name == "except" || name == "finally" || name == "from" || name == "global" || name == "import" || name == "is" || name == "lambda" || name == "len" || name == "list" || name == "math" || name == "nonlocal" || name == "not" || name == "or" || name == "pass" || name == "pyfma" || name == "raise" || name == "re" || name == "str" || name == "sys" || name == "try" || name == "with" || name == "yield") { + else if (name == "And" || name == "Array" || name == "As" || name == "Assert" || name == "Async" || name == "Await" || name == "Bool" || name == "Break" || name == "Class" || name == "Continue" || name == "Def" || name == "Del" || name == "Dict" || name == "Elif" || name == "Else" || name == "Enum" || name == "Except" || name == "Finally" || name == "For" || name == "From" || name == "Global" || name == "If" || name == "Import" || name == "In" || name == "Is" || name == "Lambda" || name == "Len" || name == "List" || name == "Math" || name == "Nonlocal" || name == "Not" || name == "Or" || name == "Pass" || name == "Pyfma" || name == "Raise" || name == "Re" || name == "Return" || name == "Str" || name == "Sys" || name == "Try" || name == "While" || name == "With" || name == "Yield" || name == "and" || name == "array" || name == "as" || name == "async" || name == "await" || name == "def" || name == "del" || name == "dict" || name == "elif" || name == "enum" || name == "except" || name == "finally" || name == "from" || name == "global" || name == "import" || name == "is" || name == "json" || name == "lambda" || name == "len" || name == "list" || name == "math" || name == "nonlocal" || name == "not" || name == "or" || name == "pass" || name == "pyfma" || name == "raise" || name == "re" || name == "str" || name == "sys" || name == "try" || name == "with" || name == "yield") { writeCamelCase(name); writeChar('_'); } @@ -22711,6 +22710,9 @@ void GenPy::visitSymbolReference(const FuSymbolReference * expr, FuPriority pare case FuId::orderedDictionaryCount: writeStringLength(expr->left.get()); break; + case FuId::jsonElementValueKind: + writeCall("JsonValueKind.get", expr->left.get()); + break; case FuId::mathNaN: include("math"); write("math.nan"); @@ -23289,6 +23291,18 @@ void GenPy::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std case FuId::matchGetCapture: writeMethodCall(obj, "group", (*args)[0].get()); break; + case FuId::jsonElementParse: + include("json"); + obj->accept(this, FuPriority::assign); + writeCall(" = json.loads", (*args)[0].get()); + break; + case FuId::jsonElementGetObject: + case FuId::jsonElementGetArray: + case FuId::jsonElementGetString: + case FuId::jsonElementGetDouble: + case FuId::jsonElementGetBoolean: + obj->accept(this, parent); + break; case FuId::mathMethod: case FuId::mathIsFinite: case FuId::mathIsNaN: @@ -23805,6 +23819,41 @@ void GenPy::writeProgram(const FuProgram * program) this->writtenTypes.clear(); this->switchBreak = false; openStringWriter(); + if (program->jsonValueKindEnum) { + writeNewLine(); + include("enum"); + write("class JsonValueKind(enum.Enum)"); + openChild(); + writeLine("OBJECT = 1"); + writeLine("ARRAY = 2"); + writeLine("STRING = 3"); + writeLine("NUMBER = 4"); + writeLine("TRUE = 5"); + writeLine("FALSE = 6"); + writeLine("NULL = 7"); + writeLine("@staticmethod"); + write("def get(e)"); + openChild(); + write("match e"); + openChild(); + writeLine("case dict():"); + writeLine("\treturn JsonValueKind.OBJECT"); + writeLine("case list():"); + writeLine("\treturn JsonValueKind.ARRAY"); + writeLine("case str():"); + writeLine("\treturn JsonValueKind.STRING"); + writeLine("case float():"); + writeLine("\treturn JsonValueKind.NUMBER"); + writeLine("case True:"); + writeLine("\treturn JsonValueKind.TRUE"); + writeLine("case False:"); + writeLine("\treturn JsonValueKind.FALSE"); + writeLine("case None:"); + writeLine("\treturn JsonValueKind.NULL"); + closeChild(); + closeChild(); + closeChild(); + } writeTypes(program); createOutputFile(); writeTopLevelNatives(program); diff --git a/libfut.cs b/libfut.cs index d1380eb6..c9ca35aa 100644 --- a/libfut.cs +++ b/libfut.cs @@ -20525,7 +20525,6 @@ protected void WriteLib(FuProgram program) WriteLine("\treturn Array.isArray(e) ? JsonValueKind.ARRAY: e === null ? JsonValueKind.NULL : JsonValueKind.OBJECT;"); CloseBlock(); CloseBlock(); - WriteNewLine(); CloseBlock(); } if (this.StringWriter) { @@ -23265,6 +23264,7 @@ void WriteNameNotKeyword(string name) case "global": case "import": case "is": + case "json": case "lambda": case "len": case "list": @@ -23570,6 +23570,9 @@ internal override void VisitSymbolReference(FuSymbolReference expr, FuPriority p case FuId.OrderedDictionaryCount: WriteStringLength(expr.Left); break; + case FuId.JsonElementValueKind: + WriteCall("JsonValueKind.get", expr.Left); + break; case FuId.MathNaN: Include("math"); Write("math.nan"); @@ -24142,6 +24145,18 @@ protected override void WriteCallExpr(FuExpr obj, FuMethod method, List case FuId.MatchGetCapture: WriteMethodCall(obj, "group", args[0]); break; + case FuId.JsonElementParse: + Include("json"); + obj.Accept(this, FuPriority.Assign); + WriteCall(" = json.loads", args[0]); + break; + case FuId.JsonElementGetObject: + case FuId.JsonElementGetArray: + case FuId.JsonElementGetString: + case FuId.JsonElementGetDouble: + case FuId.JsonElementGetBoolean: + obj.Accept(this, parent); + break; case FuId.MathMethod: case FuId.MathIsFinite: case FuId.MathIsNaN: @@ -24651,6 +24666,41 @@ public override void WriteProgram(FuProgram program) this.WrittenTypes.Clear(); this.SwitchBreak = false; OpenStringWriter(); + if (program.JsonValueKindEnum) { + WriteNewLine(); + Include("enum"); + Write("class JsonValueKind(enum.Enum)"); + OpenChild(); + WriteLine("OBJECT = 1"); + WriteLine("ARRAY = 2"); + WriteLine("STRING = 3"); + WriteLine("NUMBER = 4"); + WriteLine("TRUE = 5"); + WriteLine("FALSE = 6"); + WriteLine("NULL = 7"); + WriteLine("@staticmethod"); + Write("def get(e)"); + OpenChild(); + Write("match e"); + OpenChild(); + WriteLine("case dict():"); + WriteLine("\treturn OBJECT"); + WriteLine("case list():"); + WriteLine("\treturn ARRAY"); + WriteLine("case str():"); + WriteLine("\treturn STRING"); + WriteLine("case float():"); + WriteLine("\treturn NUMBER"); + WriteLine("case True:"); + WriteLine("\treturn TRUE"); + WriteLine("case False:"); + WriteLine("\treturn FALSE"); + WriteLine("case None:"); + WriteLine("\treturn NULL"); + CloseChild(); + CloseChild(); + CloseChild(); + } WriteTypes(program); CreateOutputFile(); WriteTopLevelNatives(program); diff --git a/libfut.js b/libfut.js index a45a2fd0..5b4d951f 100644 --- a/libfut.js +++ b/libfut.js @@ -21076,7 +21076,6 @@ export class GenJsNoModule extends GenBase this.writeLine("\treturn Array.isArray(e) ? JsonValueKind.ARRAY: e === null ? JsonValueKind.NULL : JsonValueKind.OBJECT;"); this.closeBlock(); this.closeBlock(); - this.writeNewLine(); this.closeBlock(); } if (this.#stringWriter) { @@ -23842,6 +23841,7 @@ export class GenPy extends GenPySwift case "global": case "import": case "is": + case "json": case "lambda": case "len": case "list": @@ -24151,6 +24151,9 @@ export class GenPy extends GenPySwift case FuId.ORDERED_DICTIONARY_COUNT: this.writeStringLength(expr.left); break; + case FuId.JSON_ELEMENT_VALUE_KIND: + this.writeCall("JsonValueKind.get", expr.left); + break; case FuId.MATH_NA_N: this.include("math"); this.write("math.nan"); @@ -24732,6 +24735,18 @@ export class GenPy extends GenPySwift case FuId.MATCH_GET_CAPTURE: this.writeMethodCall(obj, "group", args[0]); break; + case FuId.JSON_ELEMENT_PARSE: + this.include("json"); + obj.accept(this, FuPriority.ASSIGN); + this.writeCall(" = json.loads", args[0]); + break; + case FuId.JSON_ELEMENT_GET_OBJECT: + case FuId.JSON_ELEMENT_GET_ARRAY: + case FuId.JSON_ELEMENT_GET_STRING: + case FuId.JSON_ELEMENT_GET_DOUBLE: + case FuId.JSON_ELEMENT_GET_BOOLEAN: + obj.accept(this, parent); + break; case FuId.MATH_METHOD: case FuId.MATH_IS_FINITE: case FuId.MATH_IS_NA_N: @@ -25252,6 +25267,41 @@ export class GenPy extends GenPySwift this.#writtenTypes.clear(); this.#switchBreak = false; this.openStringWriter(); + if (program.jsonValueKindEnum) { + this.writeNewLine(); + this.include("enum"); + this.write("class JsonValueKind(enum.Enum)"); + this.openChild(); + this.writeLine("OBJECT = 1"); + this.writeLine("ARRAY = 2"); + this.writeLine("STRING = 3"); + this.writeLine("NUMBER = 4"); + this.writeLine("TRUE = 5"); + this.writeLine("FALSE = 6"); + this.writeLine("NULL = 7"); + this.writeLine("@staticmethod"); + this.write("def get(e)"); + this.openChild(); + this.write("match e"); + this.openChild(); + this.writeLine("case dict():"); + this.writeLine("\treturn OBJECT"); + this.writeLine("case list():"); + this.writeLine("\treturn ARRAY"); + this.writeLine("case str():"); + this.writeLine("\treturn STRING"); + this.writeLine("case float():"); + this.writeLine("\treturn NUMBER"); + this.writeLine("case True:"); + this.writeLine("\treturn TRUE"); + this.writeLine("case False:"); + this.writeLine("\treturn FALSE"); + this.writeLine("case None:"); + this.writeLine("\treturn NULL"); + this.closeChild(); + this.closeChild(); + this.closeChild(); + } this.writeTypes(program); this.createOutputFile(); this.writeTopLevelNatives(program); diff --git a/test/JsonElement.fu b/test/JsonElement.fu index d8366dc7..98137db0 100644 --- a/test/JsonElement.fu +++ b/test/JsonElement.fu @@ -2,7 +2,7 @@ public static class Test { public static bool Run() { - JsonElement() json; //FAIL: c cpp d java py swift TODO; cl + JsonElement() json; //FAIL: c cpp d java swift TODO; cl json.Parse("\"foo\""); if (json.ValueKind != JsonValueKind.String || json.GetString() != "foo") return false;