JM° 0.17 - 25.07.2021

Important changes:

New License = LGPLv3

Old New
getSize
getLength
loop.nr
loop.lap
Number.format
Number.style
>import
>include
_MAGIC_CONST
__MAGIC_CONST
funclet = :5.add
funclet = ::5.add
::controlFunc{ Int a }
::controlFunc( Int a )?
al = ArrayList
al = Java_ArrayList
Date.format
Date.style

Removed:

  • Switch
  • Seek
  • Object.do
  • §<<
  • &||
  • &>>
  • <file.txt>
  • <[files*.*]>

Sys-commands reorganized

Live:

´echo 4´

Pipe:

´echo 4´?.print

Buffer:

´echo 4´??.output.print

New classic Types

Print

Print "Hello!"

Echo

Echo "This "
Echo "is "
Print "a test!"

Next, Break

Count( 5 )
	If( it == 2 )
		Next
	If( it == 4 )
		Break

Return

::foo
	Return "FOO"

Set

mySet = Set(2,5,7,9)
mySet = [2,5,7,9]?

Each

list = [ 2,4,6,7,8 ]
Each( list )
	Print it

Loop

counter = 0

Loop
	counter=++
	If( counter > 10 )
		Break
	Print counter

Which

a = 4
Which( a < 3, a == 3, a == 4, a > 4 )
	Print it

PrintErr, EchoErr

PrintErr "foo"
"foo".printErr
EchoErr "foo"
"foo".echoErr

Writing of numbers

With underline:

123_456
0x89_AB_CD_EF

With exponent 'E'

123E3
123e+3
123E-3
12.3E3

New magic constant

Arguments of the application:

__ARGS

This is equal to:

app.getArgs

Assert

a = 5
a.assertIs( 5 )
a.assertIf( cur < 9 )

Atomic-Format

[ 1, 23, 456 ].each.format( "Number: {3>}" ).print

String modifiers

string  = "Foo\tBar"
literal = "Foo\tBar"?
regex1  = "Foo\tBar"??
regex2  = "Foo\tBar"¿

Table titles

tab = Table( 2 )
tab.setTitles( ["Foo", "Bar"] )
tab.getTitles

ConstLet

X = 123
cl = :X
cl.get.print

Alternative function names

::myFunc|myFunction( Int a, Int b ) = a+b

this.myFunc( 2, 3 ).print
this.myFunction( 2, 3 ).print

Null

'null' is a alias for 'nil'

nil.print
null.print

Mathematic assign to the right

5 => a
3 +=> a
1 -=> a
2 *=> a
2 /=> a
3 %=> a

Shutdown hook

app::@exit
	"This is the end!"

Event handler definition

Consts are allowed, vars must be declared

a = 2  
b = 4
C = 6

:a::@varChanged( b )
	C.print
	b.print

a = 9

Parser switch arguments

>include( "foo.jmo" )
>include = "foo.jmo"

"Namespace" becomes "Prefix"

>prefix = "Foo"

::Foo_Test

_Test
Foo_Test

"Select" with placeholder

l = [ 4,7,9,1,6,5,2 ]
l.select( 3,5,2,nil,6 ).print

Type definition

New format:

::MyType( <pars> ) ^ BaseType( <pars> ) = defaultFunc

Quick VarLet

b = [4,6,8].toVarLet

Select / Select lazy

l = Range('a', 'f').toList

l.select(3,2,6).print
l{3,2,6}.print

l.selectLazy(3,9,6,7).print
l{3,9,6,7}?.print

Update

l = Range('a', 'f').toList

l.update('x', 3, 2, 6).print

l{3,2,6} = 'x'
l.print

l.updateLazy('y', 3, 9, 6, 7).print

l{3,9,6,7}? = 'x'
l.print

Tree-Block

>>>>
	html
		body
			p,
			a
				font-size = "16px"
				font-family : "16px"
<<<<.show

Lazy Tree-Block

>>>>
	html
		body
			p,
			a
				font-size = 16px
				font-family : 16px
<<<<?.show

Table-Block

t = ||||
"foo",'a',6
"abc",'b',7
"def",'c',8
||||

t.print
x = 4

||||
2.print, 3+5, 4*2, 9
6*x, x, x-2, 3
1+x, x/2, 3.print, 'x'
5, (9*x).print, 8, 123
|||| => tab

tab.print

JM° 0.16 - 06.12.2020

Magic Variables

Some magic constants become magic variables.

E.g.: _THIS > this

this
it
loop
func
app
jmo
cur
each
nil
true
false

Sleep moved

Old:

_THIS.sleep

New:

Sys.sleep

Bit operations

123.bitAnd
123.bitOr
123.bitXor

Is not Nil

a = "foo"
If( foo.isNotNil )
	Print a

Normalize Dec

Decimal numbers will be normalizend to prevent fractals.

This can be turned off with:

>openDec

Next / Break

Count( 5 )
	If( it == 2 )
		Next
	.else( it == 4 )
		Break
	it.print

Auto-VarLet

"abcdef".amount( :b, 'd' > b ).print
"abcdef".amount( a, 'd' > a ).print
"abcdef".mem(c); c.print
"abcdef".mem(:d); d.print
::test(VarLet e)
	e.get.print

f = 1
°test(f)
g = 2
°test(:g)

Final result

Terminate the application with:

app = 0

Terminate a loop with:

loop = 0

Nil-Use

123.nilUse(11,22).print
nil.nilUse(11,22).print

Type-Use

123.typeUse("Int",1,2).print

New option for "jmo"

Direct execution:

jmo -e "Print 123"
jmo --exec "Print 123"

JM° 0.15 - 26.10.2020

Tree-Block

tree = >>>>
	body
		font-size: 16px
		margin: 20px
		line-height: 1.5
	b, strong
		font-weight: bold
<<<<

tree.show

Tree

t = Tree
t.add("Foo")
t.add("Bar")
t.show
t.get("Foo").add("Boo")
t.get("Bar").pull("Xar").pull("Tar")
t.show
t["Foo","Too","Zoo"]?
t["Bar","Xar","Tar"] = "War"

Auto-Propertys

For propertys, "Get" can be left out:

::getValueX = "myValue"

_THIS.getValueX.print
_THIS.valueX.print

For "Set" a '=' must be added:

::setValueX(x)
	x.toStr.print
_THIS.setValueX(9)
_THIS.valueX = 9

Cutting Strings

Some methods are changed

s = "abcabc"
Starting from position
s.start(3)
cabc
End at position
s.end(3)
# abc
From (first) sequence
s.from("c")
cabc
From first sequence
s.fromFirst("c")
cabc
From last sequence
s.fromLast("c")
c
After (first) sequence
s.after("c")
abc
After first sequence
s.afterFirst("c")
abc
After last sequence
s.afterLast("c")
 
Before (first) sequence
s.before("c")
ab
Before first sequence
s.beforeFirst("c")
ab
Before last sequence
s.beforeLast("c")
abcab
To (first) sequence
s.to("c")
abc
To first sequence
s.toFirst("c")
abc
To last sequence
s.toLast("c")
abcabc
Begin string with
s.begin("c")
cabcabc
Append to string
s.append("c")
abcabcc

Create a temporary VarLet as handle vor VarArgs

Object.handle now creates a temporary VarLet to the current object

h = 8.handle
h.get.print

Shortcuts for _EACH

As shortcut for _EACH you can use € and £

l = [4,9,8,2,7,3,6,5]
l.map( $$++ ).print
l.map( €++ ).print

Overwrite .toStr

::toStr = "My own string!"

°print
_THIS.print

Hot execution

Execute a String at runtime

a = 11

# Runs in container
_JMO.exec("a = 22; a.print")
a.print

# This also
"a = 33; a.print".jmo
a.print

Execution with full access to the environment.

>unsafeHotCode

# With full access to variables
_APP.exec("a = 44; a.print")
a.print

Order of arguments for .set and .put changed!

New order: Object, position1, position2, position3, ...

So its clearer: Put/Set that Object there! And it's possible to use a List (VarLet-Handle) for VarArgs

t = Table(2).add(1,2).add(3,4)
t.set(9, 2, 1)
t.put(8, 1, 3)
t.print

Now "[X, Y] = Object" is the shortcut for: "set(Object, X, Y)"

Curly brackets removed, deep-functions integrated in .get, .put, ...

l = [[[2,3]]]
l[1,1,2].print
l.get(1,1,2).print

Deep-Functionality also for Table

t = Table(2)
t.add([11,12],[13,14]).add([21,22],[23,24])
t.get(2,1,2).print

Same with .get, .pull, .set, .put

Sequence.select

l = Range('a','i').toList.print
l.select( 3,5,1,2,8 ).print
l.selectLazy( 1,3,5,7,11,13 ).print

Same for Table, Map, ...

jmo_ext.jar

BrickLinkAPI

Set a maximum of allowed calls, to respect Bricklink-limits.

BrickLinkAPI.setLimit(4000)


JM° 0.17 (soon)

New Types for Lib:

Json
Bricklink
Base64
...

New Types for Ext-Lib:

...

App-Exit-Hook

app::@exit
  "This is the end".print

Keep App running and wait for a direct call of app.exit

app.keep

Assert-Functions which throws an error at invalid values

num = 123

( num.try.assert( $ < 50 ) ).print
( num.try.assertType( "Str" ) ).print
( num.try.assertIs( 'a' ) ).print
( num.try.assert( $ < 50, "My message" ) ).print
( num.try.assertType( "Str", "My message" ) ).print
( num.try.assertIs( 'a', "My message" ) ).print

Formatting atomic objects

F = "|{5}|{3s}|{3i}|{5^d}|{}|"

5.format(F).print
1.2.format(F).print
'9'.format(F).print
true.format(F).print

For styling numbers:

123.style("????").print
123.style("0000").print
123.style("####").print

New functions for Chars, Char and Str

Chars

'3'.isNumber.print
'X'.isCaseUp.print
'x'.isCaseDown.print
' '.isBlank.print

Char

'x'.isLetter.print

Str

"".isEmpty.print

Cycle /* TODO testen */

counter = 0
c = Cycle
c.start( 1000 )

c::@
  counter =++
  ( counter >= 5 )

c.end

# app.keep

Date and day of week

d = Date(2001,11,17)
d.getDayOfWeek.print

Multi names for functions

::foo|bar|bak( Int a )
  ("foo "+a).print

this.foo(1)
this.bar(2)
this.bak(3)

Inline loop filter

9.times.breakAt(6,7,9).print
9.times.breakAtNot(1,2,3,4,6,7).print
9.times.breakIs(6,7,9).print
9.times.breakIsNot(1,2,3,4,6,7).print
9.times.breakIf( cur > 5 ).print
9.times.breakIfNot( cur < 4 ).print

Rotate a table

t = Table(2)
t.add("abc", 19)
t.add("def", 28)

t.print
t.rotate.print
t.rotate( _LEFT ).print
t.rotate( _RIGHT ).print

Null as alias for Nil

nil.print
null.print

Number with exponent

123.456e3.print
123.456E3.print

123.456e+3.print
123.456E+3.print

123.456e-3.print
123.456E-3.print

Hex/Oct/Bin now results in a number of type "Long"

0xABCD.type.print
0o1234.type.print
0b1010.type.print

Numbers with underlines

123_456_789.print
0xa_b_c_d.print
0xABCD_EF01.print
0o1_2_3_4.print
0o1234_56.print
0b1_0_1_0.print
0b1111_1101.print

Prefix replaces Namespace

>prefix("Foo")

::_Test
  "foo".print

_Test.type.print

Alternate notation for Parser-Switches

>prefix = "Foo"

... is the same as:

>prefix( "Foo" )

New classic types: Print, Echo

Print( 123 )
Print( 'a'++3, "lkj", 234 )

Echo( 123 )
Echo( 'a'++3, "lkj", 234 )

Select / Update

l = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ]
l.select(3, 2, 6).print
l.update('X', 3, 2, 6).print
l.print

Lazy version where invalid positions will be filled with 'nil'

l.selectLazy(3, 12, 6).print
l.updateLazy('Y', 3, 12, 6).print

Short versions

l{3,2,6}.print
l{3,2,6} = 'X'
l{3,12,6}?.print
l{3,12,6}? = 'x'

This works also for: Map, Table, Tree

New type: Set

s = Set
s.add( 3 )
s.add( 9 )
s.add( 1 )
s.print

String.width / String.align

s = "abcdefghi"
s.width(  3 ).print
s.width( 20 ).replace(' ', '.').print

s.align(_LEFT, 20).replace(' ', '.').print
s.align(_RIGHT, 20).replace(' ', '.').print
s.align(_CENTER, 20).replace(' ', '.').print

String.scan

""""
<html><body><table border=1><tbody>
<tr><td>1</td><td>#FFFFFF</td><td>White</td></tr>
</tbody></table></body></html>
"""" => text

text.scan("<td>", "</td>").each.print

Table-Block

t = ||||
"foo",'a',6
"abc",'b',7
"def",'c',8
||||

t.print

Tree-Block

tree = >>>>
  item

no: 123 name: "foo" type: "PART"

  color_id = 81
  new_or_used: "U"
  quantity = 11
  sale_rate = 75
  unit_price = 1.23
  <<<<

tree.print.show

Object.tryUse

a = 5.tryUse( 9d ).div(2).print
a.print

a = 5.tryUse( 9d ).div(0).print
a.print

Type extends

::Foo(Int i)
  ::foo

("Foo "+i).print

::Bar(Int i) ^ Foo(i)
  ::bar

("Bar "+i).print

Foo(1).foo
Bar(2).bar
Bar(3).foo

Calculate and assign to the right

a = 0
[3,7,5,1].each +=> a
a.print

New classic type: Which

['A','D','G','Y'].each
  Which( % <= "F", % <= "L", true).get.print

['A','D','G','Y'].each.which( $ <= "F", $ <= "L", true).print

Unterstützen