X Tutup
Skip to content

Commit 9134d7f

Browse files
committed
Updated README with correct build instructions;
updated libs included with command-line MiniScript.
1 parent 0c91325 commit 9134d7f

File tree

7 files changed

+246
-32
lines changed

7 files changed

+246
-32
lines changed

MiniScript-cpp/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ MiniScript is built with [CMake](https://cmake.org/). You can generate your desi
1212

1313
3. `cmake ../..` (or on Windows, `cmake ..\..`) to generate a makefile and related files in the build directory.
1414

15-
4. `cmake --build .` to actually do the build.
15+
4. `cmake --build . --config Release` to actually do the build.
1616

17-
If successful, you should find an executable called `miniscript` which you can install (see **Installation**, below). You'll also find a shared library (libminiscript-cpp.a) for you to link to in your own projects if you like. You can even `include()` the CMakeLists.txt of this project inside your own for clean dependency management.
17+
If successful, you should find an executable called `miniscript` (or `miniscript.exe` on Windows) which you can install (see **Installation**, below). You'll also find a shared library (libminiscript-cpp.a, miniscript-cpp.lib, or similar) for you to link to in your own projects if you like. You can even `include()` the CMakeLists.txt of this project inside your own for clean dependency management.
1818

1919
If you are only interested in the C# edition of MiniScript, there is a project file provided in the respective directory.
2020

MiniScript-cpp/lib/listUtil.ms

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@ list.contains = function(item)
99
return self.indexOf(item) != null
1010
end function
1111

12+
// lastIndexOf: returns the *last* index of the given element, optionally
13+
// before a given index. Returns null if not found.
14+
// Examples:
15+
// [7,4,7,9].lastIndexOf(7) // returns 2
16+
// [7,4,7,9].lastIndexOf(7, 2) // returns 0
17+
list.lastIndexOf = function(element, beforeIdx=null)
18+
if beforeIdx == null then i = self.len - 1 else i = beforeIdx - 1
19+
while i >= 0
20+
if self[i] == element then return i
21+
i -= 1
22+
end while
23+
return null
24+
end function
25+
26+
1227
// split: similar to string.split, this splits a list into sub-lists
1328
// by where the given delimiter element is found.
1429
list.split = function(delimiter, maxCount=null)
@@ -161,13 +176,32 @@ list.apply = function(func)
161176
end for
162177
end function
163178
179+
// applied: like list.apply, but returns the result as a new list,
180+
// without changing the list it is called on.
181+
// Example:
182+
// x = [1.1, 1.9, 3.45]
183+
// y = x.applied(@round) // y is now [1, 2, 3]; x is unchanged
184+
list.applied = function(func)
185+
result = self[:]
186+
result.apply @func
187+
return result
188+
end function
189+
164190
// apply1: same as apply, but takes 1 extra argument.
165191
list.apply1 = function(func, arg1)
166192
for i in self.indexes
167193
self[i] = func(self[i], arg1)
168194
end for
169195
end function
170196
197+
// applied1: like list.apply1, but returns the result as a new list,
198+
// without changing the list it is called on.
199+
list.applied1 = function(func, arg1)
200+
result = self[:]
201+
result.apply1 @func, arg1
202+
return result
203+
end function
204+
171205
// mean: return the average (sum divided by number of values)
172206
list.mean = function
173207
return self.sum / self.len
@@ -273,6 +307,17 @@ list.filter = function(func)
273307
end if
274308
end function
275309
310+
// filter1: like list.filter, but takes 1 extra argument for the
311+
// filter function. Note that func must be an actual function,
312+
// and not just the name of a map key in this case.
313+
list.filter1 = function(func, arg1)
314+
i = self.len - 1
315+
while i >= 0
316+
if not func(self[i], arg1) then self.remove i
317+
i = i - 1
318+
end while
319+
end function
320+
276321
// filtered: return a new list containing only the elements of self where
277322
// the given function is true. As with filter, you may also specify the
278323
// name of a map key to look up in each element of the self.
@@ -291,6 +336,54 @@ list.filtered = function(func)
291336
return result
292337
end function
293338
339+
// filtered1: like list.filter, but takes an additional argument
340+
// for the filter function.
341+
list.filtered1 = function(func, arg1)
342+
result = []
343+
for elem in self
344+
if func(elem, arg1) then result.push elem
345+
end for
346+
return result
347+
end function
348+
349+
// compress: replace each run of a given value with a single instance
350+
// of that value (in place).
351+
// Example:
352+
// x = [5,7,7,9,7,7,7]; x.compress(7) // x is now [5,7,9,7]
353+
list.compress = function(valueToCompress)
354+
i = self.len - 1
355+
compressing = false
356+
while i >= 0
357+
if self[i] == valueToCompress then
358+
if compressing then self.remove i else compressing = true
359+
else
360+
compressing = false
361+
end if
362+
i -= 1
363+
end while
364+
end function
365+
366+
// compressed: return a new list that has run of a given value
367+
// replaced with a single instance of that value.
368+
// Example:
369+
// x = [5,7,7,9,7,7,7]; x.compress(7) // x is now [5,7,9,7]
370+
list.compressed = function(valueToCompress)
371+
result = []
372+
compressing = false
373+
for value in self
374+
if value == valueToCompress then
375+
if not compressing then
376+
result.push value
377+
compressing = true
378+
end if
379+
else
380+
compressing = false
381+
result.push value
382+
end if
383+
end for
384+
return result
385+
end function
386+
294387
// valuesOf: operates on a list of maps (or other indexable type), and pulls
295388
// out the value of the given index for every element in the list, returning
296389
// theses as a new list in the same order.
@@ -374,6 +467,15 @@ runUnitTests = function
374467
end if
375468
end function
376469
470+
assertEqual [7,4,7,9].lastIndexOf(7), 2, "lastIndexOf"
471+
assertEqual [7,4,7,9].lastIndexOf(7,2), 0, "lastIndexOf"
472+
assertEqual [7,4,7,9].lastIndexOf(7,0), null, "lastIndexOf"
473+
474+
a = [5,7,7,9,7,7,7]
475+
assertEqual a.compressed(7), [5,7,9,7], "compressed"
476+
assertEqual a, [5,7,7,9,7,7,7], "compressed changed self"
477+
a.compress(7); assertEqual a, [5,7,9,7], "compress"
478+
377479
a = [-1, 42, -1, 53, 87, 345, -1, 100]
378480
assertEqual a.split(-1), [ [], [42], [53, 87, 345], [100] ]
379481
assertEqual a.split(-1, 3), [ [], [42], [53, 87, 345, -1, 100] ]
@@ -410,6 +512,13 @@ runUnitTests = function
410512
a.apply1 @round, 2
411513
assertEqual a, [1.10, 1.90, 3.45], "apply1"
412514
515+
a = [1.1, 1.899, 3.452]
516+
b = a.applied(@round)
517+
assertEqual b, [1, 2, 3], "applied"
518+
b = a.applied1(@round, 2)
519+
assertEqual b, [1.10, 1.90, 3.45], "applied1"
520+
assertEqual a, [1.1, 1.899, 3.452], "applied/applied1"
521+
413522
a = range(1, 10)
414523
isEven = function(x)
415524
return x % 2 == 0
@@ -421,6 +530,15 @@ runUnitTests = function
421530
assertEqual a, range(1, 10), "filtered"
422531
assertEqual b, [2, 4, 6, 8, 10], "filtered"
423532
533+
moreThan = function(a, b); return a > b; end function
534+
a = range(1,10)
535+
a.filter1 @moreThan, 7
536+
assertEqual a, [8, 9, 10], "filter1"
537+
a = range(1,10)
538+
b = a.filtered1(@moreThan, 7)
539+
assertEqual a, range(1, 10), "filtered1"
540+
assertEqual b, [8, 9, 10], "filtered1"
541+
424542
a = [{"x":42, "keep":true}, {"x":123, "keep":false}, {"x":0, "keep":true}]
425543
a.filter "keep"
426544
assertEqual a, [{"x":42, "keep":true}, {"x":0, "keep":true}], "filter by key"

MiniScript-cpp/lib/mapUtil.ms

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
map.get = function(key, defaultValue=null)
88
m = self
99
while m
10-
if m.hasIndex(key) then return m[key]
10+
if m.hasIndex(@key) then return m[@key]
1111
if not m.hasIndex("__isa") then break
1212
m = m.__isa
1313
end while
@@ -119,12 +119,15 @@ runUnitTests = function
119119
end if
120120
end function
121121

122-
d = {"one":"ichi", "two":"ni", "three":"san", "four":"shi", "five":"go"}
122+
d = {"one":"ichi", "two":"ni", "three":"san", "four":"shi", "five":"go", @print: "six"}
123123

124124
testing = "get"
125125
assertEqual d.get("one", 1), "ichi"
126126
assertEqual d.get("ten", 10), 10
127127
assertEqual d.get("twenty"), null
128+
assertEqual d.get(@print), "six"
129+
130+
d.remove @print
128131

129132
testing = "hasValue"
130133
assertEqual d.hasValue("ni"), true

MiniScript-cpp/lib/mathUtil.ms

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,43 @@ clamp = function(x, minval=0, maxval=1)
135135
return x
136136
end function
137137

138+
// max: returns the greater of two values.
139+
// (Note: if you have more than two, consider importing listUtil
140+
// and using list.max instead.)
141+
max = function(a, b)
142+
if b > a then return b else return a
143+
end function
144+
145+
// min: returns the lesser of two values.
146+
// (As above, also consider list.min from listUtil.)
147+
min = function(a, b)
148+
if b < a then return b else return a
149+
end function
150+
138151
// numToStr: converts a number to a string, with a specified precision
139152
// (number of digits past the decimal place). Trailing zeros will be
140153
// added as needed to get the decimal point at the right place.
141154
numToStr = function(n, precision=null)
142155
if precision == null then return str(n)
143-
s = str(round(n, precision))
144-
if precision > 0 then
145-
dotPos = s.indexOf(".")
146-
if dotPos == null then
147-
s = s + "." + "0" * precision
148-
else if dotPos > s.len - precision - 1 then
149-
s = s + "0" * (dotPos - s.len + precision + 1)
150-
end if
156+
if not n isa number or not precision isa number then
157+
print "numToStr error: arguments must be numbers."
158+
return
151159
end if
152-
return s
160+
if precision <= 0 or n == 1/0 or n == -1/0 or n != n then return str(round(n, precision))
161+
negative = n < 0; n = abs(n)
162+
digits = [floor(n)]
163+
for i in range(1, precision)
164+
d = floor(n * 10^i) % 10
165+
digits.push d
166+
end for
167+
if (n * 10^precision) % 1 >= 0.5 then
168+
for i in range(digits.len - 1)
169+
digits[i] += 1
170+
if digits[i] < 10 or i == 0 then break
171+
digits[i] = 0
172+
end for
173+
end if
174+
return "-" * negative + digits.pull + "." + digits.join("")
153175
end function
154176

155177
runUnitTests = function
@@ -175,12 +197,18 @@ runUnitTests = function
175197
assertEqual mover.y, 30, "moveTowardsXY"
176198
assertEqual moveTowardsXY(mover, target, 10), false
177199

178-
assertEqual numToStr(pi, 2), "3.14"
179-
assertEqual numToStr(1.23, 3), "1.230"
180-
assertEqual numToStr(1.23), "1.23"
181-
assertEqual numToStr(12345.67, -2), "12300"
182-
assertEqual numToStr(2, 3), "2.000"
183-
200+
assertEqual numToStr(pi, 2), "3.14", "numToStr"
201+
assertEqual numToStr(pi, 4), "3.1416", "numToStr"
202+
assertEqual numToStr(pi, 12), "3.141592653590", "numToStr"
203+
assertEqual numToStr(1.23, 3), "1.230", "numToStr"
204+
assertEqual numToStr(1.23), "1.23", "numToStr"
205+
assertEqual numToStr(12345.67, -2), "12300", "numToStr"
206+
assertEqual numToStr(2, 3), "2.000", "numToStr"
207+
assertEqual numToStr(2/3, 12), "0.666666666667", "numToStr"
208+
assertEqual numToStr(41.9999, 2), "42.00", "numToStr"
209+
assertEqual numToStr(42 - 1E-12, 5), "42.00000", "numToStr"
210+
assertEqual numToStr(-pi, 4), "-3.1416", "numToStr"
211+
184212
if errorCount == 0 then
185213
print "All tests passed. Woot!"
186214
else

MiniScript-cpp/lib/matrixUtil.ms

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ end function
8282
// Instance methods: call these on a Matrix instance.
8383
//----------------------------------------------------------------------
8484
85+
// m.size: return [rows, columns] size of the matrix
86+
Matrix.size = function
87+
return [self.rows, self.columns]
88+
end function
89+
8590
// m.row: return the given row of matrix m as a single-row matrix.
8691
Matrix.row = function(zeroBasedRowNum)
8792
return Matrix.fromList(self.elem[zeroBasedRowNum])
@@ -197,6 +202,11 @@ Matrix.times = function(m2)
197202
if m2 isa Matrix then m2 = m2.elem
198203
if m2 isa list then
199204
// matrix multiplication
205+
if m2.len != self.columns then
206+
print "Matrix.times error: incompatible sizes " +
207+
self.size + " and " + [m2.len, len(m2[0])]
208+
exit
209+
end if
200210
result = Matrix.ofSize(self.rows, m2[0].len)
201211
for r in result.rowRange
202212
resultRow = result.elem[r]
@@ -246,26 +256,32 @@ Matrix.equals = function(m2)
246256
return self.elem == m2elems
247257
end function
248258
259+
// Matrix.round: rounds all numbers in the matrix.
260+
Matrix.round = function(decimalPlaces=0)
261+
for row in self.elem
262+
for i in row.indexes
263+
row[i] = round(row[i], decimalPlaces)
264+
end for
265+
end for
266+
end function
267+
249268
// Matrix.print: prints matrix data, with some formatting options.
250269
// fieldWidth: minimum number of characters for each element
251270
// precision: if non-null, round each element to this many digits
252271
// columnSep: extra string printed between elements within a row
253272
// rowSep: extra string printed between rows; defaults to text.delimiter
254273
Matrix.print = function(fieldWidth=10, precision=null, columnSep="", rowSep=null)
255-
oldDelim = text.delimiter; text.delimiter = ""
256-
if rowSep == null then rowSep = oldDelim
274+
if rowSep == null then rowSep = text.delimiter
257275
for row in self.elem
258-
firstInRow = true
276+
line = []
259277
for elem in row
260278
s = mathUtil.numToStr(elem, precision)
279+
if s.len >= fieldWidth and s.indexOf(".") != null then s = s[:fieldWidth-1]
261280
if s.len < fieldWidth then s = " "*(fieldWidth-s.len) + s
262-
if not firstInRow then print columnSep
263-
print s
264-
firstInRow = false
281+
line.push s
265282
end for
266-
print rowSep
283+
print line.join(columnSep), rowSep
267284
end for
268-
text.delimiter = oldDelim
269285
end function
270286
271287

MiniScript-cpp/lib/qa.ms

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ end function
3232
// assertEqual: abort if the first two parameters are not equal.
3333
// Additional descriptive note is optional.
3434
assertEqual = function(actual, expected, note)
35-
if actual == expected then return
35+
if @actual == @expected then return
3636
msg = "Assert failed"
3737
if note != null then msg = msg + " (" + note + ")"
38-
msg = msg + ": expected `" + expected + "`, but got `" + actual + "`"
38+
msg = msg + ": expected `" + @expected + "`, but got `" + @actual + "`"
3939
abort msg
4040
end function
4141

@@ -50,7 +50,9 @@ typeOf = function(value)
5050
if value isa map then
5151
mapType = value
5252
if value.hasIndex("__isa") then mapType = value.__isa
53-
if namedMaps.hasIndex(mapType) then return namedMaps[mapType]
53+
for kv in namedMaps
54+
if refEquals(kv.key, mapType) then return kv.value
55+
end for
5456
return "map"
5557
end if
5658
return "unknown"
@@ -59,11 +61,11 @@ end function
5961
// assertType: abort if the first parameter is not of the specified type.
6062
// Additional descriptive note is optional.
6163
assertType = function(value, type, note)
62-
if value isa type then return
64+
if @value isa type then return
6365
msg = "Assert failed"
6466
if note != null then msg = msg + " (" + note + ")"
6567
msg = msg + ": expected type " + namedMaps[type] +
66-
", but got a " + typeOf(value) + " (" + value + ")"
68+
", but got a " + typeOf(@value) + " (" + @value + ")"
6769
abort msg
6870
end function
6971

0 commit comments

Comments
 (0)
X Tutup