annotate 2-Io/day3-DSL.io @ 67:8906b5a4517f

Calculate and validate boxes The solver now creates answers for valid sudoku, but doesn't reject invalid ones (e.g. dupe in column)
author IBBoard <dev@ibboard.co.uk>
date Sat, 07 Oct 2017 15:07:34 +0100
parents 409249712590
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
1 # Creating a simple "domain-specific language"
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
2 # (Except it's not really - it's just a little extension to support
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
3 # the "{ key:value[, key:value[…]] }" format of specifying dictionaries)
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
4
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
5 # Because this is a string then we can do it at any time!
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
6 OperatorTable addAssignOperator(":", "atPutThing")
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
7
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
8 # curlyBrackets is an automatically invoked function from the parser whenever
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
9 # it encounters curly brackets.
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
10 # This is hidden black magic that you need to know about to override it.
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
11 # It appears to call the method for all of the content within the brackets.
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
12 curlyBrackets := method(
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
13 # Create a map
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
14 map := Map clone
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
15 # Foreach arg that got passed (each comma-separated line within the brackets)
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
16 # then run that on the map
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
17 # Note: It isn't clear why ":" operates on the map at this point
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
18 # The book says "we'll execute `map atPutThing(a, b)`" but why?
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
19 # Colon was originally on a string, not the map, so how does it know to invoke on the map?
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
20 call message arguments foreach(arg,
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
21 # Based on the following println then it is already "atPutThing(a, b)" by this point
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
22 # but the ordering still doesn't make sense.
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
23 # See also http://iolanguage.org/guide/guide.html#Syntax-Operators
45
8a2451a7b86e Add another thought about how the ":" operator works
IBBoard <dev@ibboard.co.uk>
parents: 44
diff changeset
24 #
8a2451a7b86e Add another thought about how the ":" operator works
IBBoard <dev@ibboard.co.uk>
parents: 44
diff changeset
25 # It *might* be a side-effect of how addAssignOperator works and then the map hijacks
8a2451a7b86e Add another thought about how the ":" operator works
IBBoard <dev@ibboard.co.uk>
parents: 44
diff changeset
26 # the values, but that isn't clear from the book OR the documentation!
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
27 #arg println
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
28 map doMessage(arg)
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
29 )
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
30 # Return the map (last line's return is the return)
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
31 map
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
32 )
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
33
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
34 Map atPutThing := method(
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
35 # Call the standard method
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
36 self atPut(
44
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
37 # And pull the call args to pass through
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
38 # NOTE: arg 1 has its quotes stripped automatically because it's a number
6347bacb3be7 Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents: 43
diff changeset
39 # or some other magic!
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
40 call evalArgAt(0) asMutable removePrefix("\"") removeSuffix("\""),
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
41 call evalArgAt(1)
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
42 )
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
43 )
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
44
46
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
45 # Note: Trailing commas break things in COMPLETELY CRYPTIC WAYS
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
46 # This is because we use doString, which executes it as a program,
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
47 # BUT the stack trace doesn't make this clear, so you end up chasing
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
48 # bugs in ENTIRELY THE WRONG PART OF THE CODE.
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
49 # Eval considered harmful.
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
50 the_string := "{
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
51 \"foo\": \"12345\",
46
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
52 \"bar\": \"7890\"
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
53 }"
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
54
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
55 phoneNumbers := doString(the_string)
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
56 phoneNumbers keys println
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
57 phoneNumbers values println
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
58
46
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
59 # It feels like implementing something like this should work,
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
60 # but it doesn't because "Number does not respond to ':'"
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
61 # because we assigned ":" as an assignment operator (like :=)
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
62 # and not as a normal operator, although it's then EVEN LESS CLEAR
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
63 # how the code in curlyBrackets works
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
64 # Also, Io Language docs are poor and don't make it clear how to:
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
65 # a) define a range that works; or
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
66 # b) do ANYTHING with the OperatorTable
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
67 Number atPutThing := method(
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
68 call println
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
69 return Range (call target) to(call evalArgAt(1))
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
70 )
eac30c1b92da Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents: 45
diff changeset
71
47
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
72
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
73 # But presumably this will break, because there's no "atPutThing" method
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
74 a := 1
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
75 b := 5
47
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
76 #range := a : b
43
d2764720ea17 Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
77 # Yep - "Exception: Number does not respond to ':'"
47
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
78 # So you've got to be careful for reusable operators
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
79
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
80 # We can't even define the method and have it Just Work™.
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
81 # I know officially give up. This is undocumented and unclear.
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
82 #
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
83 #atPutThing := method(start, end,
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
84 # return Range(start) to(end)
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
85 #)
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
86 #
409249712590 Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents: 46
diff changeset
87 #range : 1 3