about summary refs log tree commit diff stats
path: root/subx
Commit message (Collapse)AuthorAgeFilesLines
* 5085 - 'assort' phase done!Kartik Agaram2019-04-124-408/+510
| | | | | | | | | | | | | | | | | Current plan for SubX translator: $ cat files.subx ... |assort |pack |survey |hex > a.out Higher-level notations will be inserted at the start of the pipeline. The first (and needed for bootstrapping) is for string literals. $ cat files.subx ... |string-literals |assort |pack |survey |hex > a.out Alternatively, we should check how often we use string literals and just convert them by hand. They're used all over in tests, and converting them would make tests hard (even harder) to read.
* 5084Kartik Agaram2019-04-117-9/+9
|
* 5083Kartik Agaram2019-04-111-1/+2
|
* 5082Kartik Agaram2019-04-111-2/+3
|
* 5080Kartik Agaram2019-04-116-110/+78
|
* 5078Kartik Agaram2019-04-111-4/+4
|
* 5076Kartik Agaram2019-04-101-0/+0
|
* 5075Kartik Agaram2019-04-101-0/+0
|
* 5074Kartik Agaram2019-04-1012-125/+290
| | | | | | | | | | | | | Fail early when writing to a fake file runs out of space. Makes debugging tests easier. Reads from files, on the other hand, are only buffering to a temporary stream, so it makes sense to silently stop when they run out of space. In the process I uncovered a testing bug in pack.subx: I was missing a trailing space in the expected result, but the test still passed because the space was getting truncated. Being principled about aborting on overflow by default will help avoid such issues.
* 5073Kartik Agaram2019-04-101-2/+2
|
* 5072Kartik Agaram2019-04-101-15/+1
|
* 5071Kartik Agaram2019-04-101-12/+15
|
* 5070Kartik Agaram2019-04-101-1/+1
|
* 5069Kartik Agaram2019-04-101-7/+7
|
* 5068Kartik Agaram2019-04-101-1/+1
| | | | Temporary title for HN submission.
* 5067Kartik Agaram2019-04-101-11/+11
|
* 5066Kartik Agaram2019-04-101-253/+223
|
* 5064Kartik Agaram2019-04-071-3/+2
|
* 5063Kartik Agaram2019-04-071-69/+0
|
* 5062Kartik Agaram2019-04-062-391/+460
|
* 5061Kartik Agaram2019-04-061-1/+1
|
* 5060Kartik Agaram2019-04-0610-13/+273
|
* 5059Kartik Agaram2019-04-0517-43/+43
|
* 5058Kartik Agaram2019-04-054-246/+252
|
* 5057Kartik Agaram2019-04-051-1/+35
|
* 5056Kartik Agaram2019-04-057-2/+144
|
* 5055 - new phase: merge fragment of segmentsKartik Agaram2019-04-041-0/+1102
|
* 5054Kartik Agaram2019-04-032-4/+3
|
* 5053Kartik Agaram2019-04-039-154/+266
| | | | | | write-stream-buffered isn't a clean abstraction. Ignoring the 'read' index of a stream is a hack. It's just saving us the trouble of a rewind-stream. So make it a helper of pack.subx rather than part of the standard library.
* 5052Kartik Agaram2019-04-022-99/+127
|
* 5051 - done compiling SIB operandsKartik Agaram2019-04-022-3/+671
| | | | Done with pack.subx?!
* 5050 - compile ModR/M operandsKartik Agaram2019-04-023-3/+809
|
* 5049Kartik Agaram2019-04-021-100/+196
|
* 5048Kartik Agaram2019-04-011-12/+12
|
* 5047Kartik Agaram2019-04-011-3/+3
|
* 5046Kartik Agaram2019-04-012-72/+52
|
* 5045Kartik Agaram2019-04-011-8/+8
|
* 5044Kartik Agaram2019-04-012-3/+248
|
* 5043Kartik Agaram2019-04-011-0/+3
|
* 5042Kartik Agaram2019-03-312-33/+35
|
* 5041 - compile displacement operandsKartik Agaram2019-03-312-13/+565
|
* 5040 - compile immediate operandsKartik Agaram2019-03-302-16/+556
|
* 5039 - compile opcodesKartik Agaram2019-03-302-6/+1011
|
* 5038Kartik Agaram2019-03-292-11/+181
|
* 5037Kartik Agaram2019-03-2910-32/+32
|
* 5036Kartik Agaram2019-03-292-34/+65
|
* 5034Kartik Agaram2019-03-292-50/+225
|
* 5032Kartik Agaram2019-03-291-1/+2
|
* 5031Kartik Agaram2019-03-291-9/+10
|
* 5030 - docs for library functions created so farKartik Agaram2019-03-291-12/+137
|
[x, y: uint8, ch: uint16] proc `%`(p: Pix): JsonNode = result = %* { "x" : % p.x, "y" : % p.y, "ch" : % p.ch } proc testJson() = # Tests inspired by own use case (with some additional tests). # This should succeed. type Point[T] = object x, y: T ReplayEventKind = enum FoodAppeared, FoodEaten, DirectionChanged ReplayEvent = object time*: float case kind*: ReplayEventKind of FoodAppeared, FoodEaten: foodPos*: Point[float] case subKind*: bool of true: it: int of false: ot: float of DirectionChanged: playerPos*: float Replay = ref object events*: seq[ReplayEvent] test: int test2: string test3: bool testNil: string var x = Replay( events: @[ ReplayEvent( time: 1.2345, kind: FoodEaten, foodPos: Point[float](x: 5.0, y: 1.0), subKind: true, it: 7 ) ], test: 18827361, test2: "hello world", test3: true, testNil: "nil" ) let node = %x let y = to(node, Replay) doAssert y.events[0].time == 1.2345 doAssert y.events[0].kind == FoodEaten doAssert y.events[0].foodPos.x == 5.0 doAssert y.events[0].foodPos.y == 1.0 doAssert y.test == 18827361 doAssert y.test2 == "hello world" doAssert y.test3 doAssert y.testNil == "nil" # Test for custom object variants (without an enum) and with an else branch. block: type TestVariant = object name: string case age: uint8 of 2: preSchool: string of 8: primarySchool: string else: other: int var node = %{ "name": %"Nim", "age": %8, "primarySchool": %"Sandtown" } var result = to(node, TestVariant) doAssert result.age == 8 doAssert result.name == "Nim" doAssert result.primarySchool == "Sandtown" node = %{ "name": %"⚔️Foo☢️", "age": %25, "other": %98 } result = to(node, TestVariant) doAssert result.name == node["name"].getStr() doAssert result.age == node["age"].getInt().uint8 doAssert result.other == node["other"].getBiggestInt() # TODO: Test object variant with set in of branch. # TODO: Should we support heterogeneous arrays? # Tests that verify the error messages for invalid data. block: type Person = object name: string age: int var node = %{ "name": %"Dominik" } try: discard to(node, Person) doAssert false except KeyError as exc: doAssert("age" in exc.msg) except: doAssert false node["age"] = %false try: discard to(node, Person) doAssert false except JsonKindError as exc: doAssert("age" in exc.msg) except: doAssert false type PersonAge = enum Fifteen, Sixteen PersonCase = object name: string case age: PersonAge of Fifteen: discard of Sixteen: id: string try: discard to(node, PersonCase) doAssert false except JsonKindError as exc: doAssert("age" in exc.msg) except: doAssert false # Test the example in json module. block: let jsonNode = parseJson(""" { "person": { "name": "Nimmer", "age": 21 }, "list": [1, 2, 3, 4] } """) type Person = object name: string age: int Data1 = object # TODO: Codegen bug when changed to ``Data``. person: Person list: seq[int] var data = to(jsonNode, Data1) doAssert data.person.name == "Nimmer" doAssert data.person.age == 21 doAssert data.list == @[1, 2, 3, 4] # Test non-variant enum fields. block: type EnumType = enum Foo, Bar TestEnum = object field: EnumType var node = %{ "field": %"Bar" } var result = to(node, TestEnum) doAssert result.field == Bar # Test ref type in field. block: var jsonNode = parseJson(""" { "person": { "name": "Nimmer", "age": 21 }, "list": [1, 2, 3, 4] } """) type Person = ref object name: string age: int Data = object person: Person list: seq[int] var data = to(jsonNode, Data) doAssert data.person.name == "Nimmer" doAssert data.person.age == 21 doAssert data.list == @[1, 2, 3, 4] jsonNode = parseJson(""" { "person": null, "list": [1, 2, 3, 4] } """) data = to(jsonNode, Data) doAssert data.person.isNil block: type FooBar = object field: float let x = parseJson("""{ "field": 5}""") let data = to(x, FooBar) doAssert data.field == 5.0 block: type BirdColor = object name: string rgb: array[3, float] type Bird = object age: int height: float name: string colors: array[2, BirdColor] var red = BirdColor(name: "red", rgb: [1.0, 0.0, 0.0]) var blue = Birdcolor(name: "blue", rgb: [0.0, 0.0, 1.0]) var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue]) let jnode = %b let data = jnode.to(Bird) doAssert data == b block: type MsgBase = ref object of RootObj name*: string MsgChallenge = ref object of MsgBase challenge*: string let data = %*{"name": "foo", "challenge": "bar"} let msg = data.to(MsgChallenge) doAssert msg.name == "foo" doAssert msg.challenge == "bar" block: type Color = enum Red, Brown Thing = object animal: tuple[fur: bool, legs: int] color: Color var j = parseJson(""" {"animal":{"fur":true,"legs":6},"color":"Red"} """) let parsed = to(j, Thing) doAssert parsed.animal.fur doAssert parsed.animal.legs == 6 doAssert parsed.color == Red block: when not defined(js): # disable on js because of #12492 type Car = object engine: tuple[name: string, capacity: float] model: string let j = """ {"engine": {"name": "V8", "capacity": 5.5}, "model": "Skyline"} """ var i = 0 proc mulTest(): JsonNode = inc i return parseJson(j) let parsed = mulTest().to(Car) doAssert parsed.engine.name == "V8" doAssert i == 1 block: # Option[T] support! type Car1 = object # TODO: Codegen bug when `Car` engine: tuple[name: string, capacity: Option[float]] model: string year: Option[int] let noYear = """ {"engine": {"name": "V8", "capacity": 5.5}, "model": "Skyline"} """ let noYearParsed = parseJson(noYear) let noYearDeser = to(noYearParsed, Car1) doAssert noYearDeser.engine.capacity == some(5.5) doAssert noYearDeser.year.isNone doAssert noYearDeser.engine.name == "V8" # Issue #7433 type Obj2 = object n1: int n2: Option[string] n3: bool var j = %*[ { "n1": 4, "n2": "ABC", "n3": true }, { "n1": 1, "n3": false }, { "n1": 1, "n2": "XYZ", "n3": false } ] let jDeser = j.to(seq[Obj2]) doAssert jDeser[0].n2.get() == "ABC" doAssert jDeser[1].n2.isNone() # Issue #6902 type Obj = object n1: int n2: Option[int] n3: Option[string] n4: Option[bool] var j0 = parseJson("""{"n1": 1, "n2": null, "n3": null, "n4": null}""") let j0Deser = j0.to(Obj) doAssert j0Deser.n1 == 1 doAssert j0Deser.n2.isNone() doAssert j0Deser.n3.isNone() doAssert j0Deser.n4.isNone() # Table[T, Y] support. block: type Friend = object name: string age: int Dynamic = object name: string friends: Table[string, Friend] let data = """ {"friends": { "John": {"name": "John", "age": 35}, "Elizabeth": {"name": "Elizabeth", "age": 23} }, "name": "Dominik"} """ let dataParsed = parseJson(data) let dataDeser = to(dataParsed, Dynamic) doAssert dataDeser.name == "Dominik" doAssert dataDeser.friends["John"].age == 35 doAssert dataDeser.friends["Elizabeth"].age == 23 # JsonNode support block: type Test = object name: string fallback: JsonNode let data = """ {"name": "FooBar", "fallback": 56.42} """ let dataParsed = parseJson(data) let dataDeser = to(dataParsed, Test) doAssert dataDeser.name == "FooBar" doAssert dataDeser.fallback.kind == JFloat doAssert dataDeser.fallback.getFloat() == 56.42 # int64, float64 etc support. block: type Test1 = object a: int8 b: int16 c: int32 d: int64 e: uint8 f: uint16 g: uint32 h: uint64 i: float32 j: float64 let data = """ {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9.9, "j": 10.10} """ let dataParsed = parseJson(data) let dataDeser = to(dataParsed, Test1) doAssert dataDeser.a == 1 doAssert dataDeser.f == 6 doAssert dataDeser.i == 9.9'f32 # deserialize directly into a table block: let s = """{"a": 1, "b": 2}""" let t = parseJson(s).to(Table[string, int]) when not defined(js): # For some reason on the JS backend `{"b": 2, "a": 0}` is # sometimes the value of `t`. This needs investigation. I can't # reproduce it right now in an isolated test. doAssert t["a"] == 1 doAssert t["b"] == 2 block: # bug #8037 type Apple = distinct string String = distinct Apple Email = distinct string MyList = distinct seq[int] MyYear = distinct Option[int] MyTable = distinct Table[string, int] MyArr = distinct array[3, float] MyRef = ref object name: string MyObj = object color: int MyDistRef = distinct MyRef MyDistObj = distinct MyObj Toot = object name*: String email*: Email list: MyList year: MyYear dict: MyTable arr: MyArr person: MyDistRef distfruit: MyDistObj dog: MyRef fruit: MyObj emails: seq[String] var tJson = parseJson(""" { "name":"Bongo", "email":"bongo@bingo.com", "list": [11,7,15], "year": 1975, "dict": {"a": 1, "b": 2}, "arr": [1.0, 2.0, 7.0], "person": {"name": "boney"}, "dog": {"name": "honey"}, "fruit": {"color": 10}, "distfruit": {"color": 11}, "emails": ["abc", "123"] } """) var t = to(tJson, Toot) doAssert string(t.name) == "Bongo" doAssert string(t.email) == "bongo@bingo.com" doAssert seq[int](t.list) == @[11,7,15] doAssert Option[int](t.year).get() == 1975 doAssert Table[string,int](t.dict)["a"] == 1 doAssert Table[string,int](t.dict)["b"] == 2 doAssert array[3, float](t.arr) == [1.0,2.0,7.0] doAssert MyRef(t.person).name == "boney" doAssert MyObj(t.distFruit).color == 11 doAssert t.dog.name == "honey" doAssert t.fruit.color == 10 doAssert seq[string](t.emails) == @["abc", "123"] block test_table: var y = parseJson("""{"a": 1, "b": 2, "c": 3}""") var u = y.to(MyTable) var v = y.to(Table[string, int]) doAssert Table[string, int](u)["a"] == 1 doAssert Table[string, int](u)["b"] == 2 doAssert Table[string, int](u)["c"] == 3 doAssert v["a"] == 1 block primitive_string: const kApple = "apple" var u = newJString(kApple) var v = u.to(Email) var w = u.to(Apple) var x = u.to(String) doAssert string(v) == kApple doAssert string(w) == kApple doAssert string(x) == kApple block test_option: var u = newJInt(1137) var v = u.to(MyYear) var w = u.to(Option[int]) doAssert Option[int](v).get() == 1137 doAssert w.get() == 1137 block test_object: var u = parseJson("""{"color": 987}""") var v = u.to(MyObj) var w = u.to(MyDistObj) doAssert v.color == 987 doAssert MyObj(w).color == 987 block test_ref_object: var u = parseJson("""{"name": "smith"}""") var v = u.to(MyRef) var w = u.to(MyDistRef) doAssert v.name == "smith" doAssert MyRef(w).name == "smith" block: # bug #12015 type Cluster = object works: tuple[x, y: uint8, ch: uint16] # working fails: Pix # previously broken let data = (x: 123'u8, y: 53'u8, ch: 1231'u16) let c = Cluster(works: data, fails: data) let cFromJson = (% c).to(Cluster) doAssert c == cFromJson block: # bug related to #12015 type PixInt = tuple[x, y, ch: int] SomePix = Pix | PixInt Cluster[T: SomePix] = seq[T] ClusterObject[T: SomePix] = object data: Cluster[T] RecoEvent[T: SomePix] = object cluster: seq[ClusterObject[T]] let data = @[(x: 123'u8, y: 53'u8, ch: 1231'u16)] var c = RecoEvent[Pix](cluster: @[ClusterObject[Pix](data: data)]) let cFromJson = (% c).to(RecoEvent[Pix]) doAssert c == cFromJson block: # ref objects with cycles. type Misdirection = object cycle: Cycle Cycle = ref object foo: string cycle: Misdirection let data = """ {"cycle": null} """ let dataParsed = parseJson(data) let dataDeser = to(dataParsed, Misdirection) block: # ref object from #12316 type Foo = ref Bar Bar = object discard "null".parseJson.to Foo block: # named array #12289 type Vec = array[2, int] let arr = "[1,2]".parseJson.to Vec doAssert arr == [1,2] block: # test error message in exception type MyType = object otherMember: string member: MySubType MySubType = object somethingElse: string list: seq[MyData] MyData = object value: int let jsonNode = parseJson(""" { "otherMember": "otherValue", "member": { "somethingElse": "something", "list": [{"value": 1}, {"value": 2}, {}] } } """) try: let tmp = jsonNode.to(MyType) doAssert false, "this should be unreachable" except KeyError: doAssert getCurrentExceptionMsg().contains ".member.list[2].value" testJson() static: testJson()