This release is different. Previous release has highly prioritized backward compatebility. While this still is a goal, this is the version that adds some missing features and make design adjustments that might break existing code.
.foreach (e in list) {
.print e
}
.foreach (e1,e2 in list1,list2) {
.print e1+","+e2
}
.foreach (x in List().add(1,10,100) if x>5) {
.print x
}
.foreach (i,e in list)
.print "Element number "+i+" is "+ e
}.fill and .fillword directives now supports iterators. If only one argument is given it will
iterate through the value:
.var list = List().add(1,2,3,4) .fill list .fillword list
// Easy way for defining a list .var myList = [1,2,3,"Hello", "world", ["nested", "list"]] .var myList2= [ "one", "two", // <- You can leave an extra comma at the end ]
// Simple loop lists .var myList3= [x foreach x in range(5)] // Same as List().add(0,1,2,3,4) .fill [(x+3)*2 foreach x in range(2)] // Same as .byte 6,8 // Short notation: If you leave out the value expression the iterated element is used .var standard = [x foreach x in range(5)] .var short = [foreach x in range(5)] // Short notation: If you leave out the iterator name then 'e' is used .var standard = [x foreach x in range(5)] .var short = [e foreach in range(5)] .var shortest = [foreach in range(5)] // Nested loops .var vectors = [Vector(x,y,z) foreach x in range(2) foreach y in range(5) foreach z in range(3)] // Filtering .var wordsAndNulls = [null, "Hello", null, null, "World"] .var words = [x foreach x in wordsAndNulls if x!=null] // Enumeration (one more id than iterargs) .var wordsEnum = [""+i+"."+word foreach i,word in ["pancake", "bike", "bed"]] // "0.pancake", "1.bike", "2.bed" //Multiple iterators .var vectors1 = [Vector(1,0,0), Vector(0,1,0), Vector(0,0,1)] .var vectors2 = [Vector(9,8,7), Vector(6,5,4), Vector(3,2,1)] .print [v1*v2 foreach v1,v2 in vectors1,vectors2] // prints [9,5,1] // Nesting .print [[y foreach y in range(x+1)] foreach x in range(4)]
// Normal Hashtables
.var tab = { "age":27, "name":"Curt" }
.var nestedTab = { "nested":{"age":28, "numbers": [0,10,20,30]}, }
// Loop
.var dict = { x:x*10 foreach k,v in range(3)}
// Multiple iterators + filters
.var keys = [ 1, 2, null, 3, null, 4]
.var values = [ null,"two", null, null, "x", 4]
.var dict = { k:v foreach k,v in keys, values if k!=null && v!=null}
// Enum
.var dict2 = {i:v foreach i,v in ["zero","one","two","three"]}
//Creating Vec2d by using struct expression, The used struct is defined '{#struct':
.struct Vec2d {x , y}
.var v1 = {#Vec2d x:4, y:27+4 }
// The fields you don't assign will be null
.print {#Vec2d }
//Name spacing
.struct @lib.Test {a , b, c}
.var x = {#@lib.Test a:2*25, b:false?5:10 }
//Anonymous struct (Don't give a struct and a value will be created with the given fields)
.var y = {# name:"Casper", age:27 }
TODO: Dedicated example will come here.
// Generate persons with random ages and favorite
.var firstNames = ["James", "Lars", "Kirk", "Robert", "Steven", "Joe", "Brad" ]
.var sirNames = ["Johanson", "Connelly", "Hayek", "Jones", "Comer", "Lawrence", "Dench"]
.var colors = ["Red", "Green","Blue", "Yellow", "Orange", "Grey", "White", "Pink"]
.var persons = [{# name:first+" "+last,
age:floor(random()*60),
favoriteColor:colors.get(random()*colors.size()),
} foreach first in firstNames foreach last in sirNames].shuffle()
// Find the oldest person
.print @"\nOldest person:\n" + persons.aggregate((p1,p2)=>p2.age>p1.age?p2:p1)
// Find persons who have an age between 20 and 25
.print @"\nPersons between 20 and 25:\n" + @"\n".join(persons.where(p=>20<=p.age && p.age<25))
// Find the most common favorite color
.var groups = persons.groupBy(p=>p.favoriteColor)
.var groupWithMostPersons = groups.entryIter().aggregate((e1,e2)=>e2.value.size()>e1.value.size()?e2:e1)
.print @"\nThe most common favorite color is: \n" + groupWithMostPersons.key
// Print the name of the persons with the most common favorite color
.print @"\nPersons with the most common favorite color is: \n" + @"\n".join(groupWithMostPersons.value.select(p=>p.name))
/* The output looks like this:
Oldest person:
{# name: "Brad Dench", favoriteColor: "White", age: 59}
Persons between 20 and 25:
{# name: "Lars Jones", favoriteColor: "Yellow", age: 22}
{# name: "Steven Dench", favoriteColor: "Green", age: 23}
{# name: "Steven Hayek", favoriteColor: "Red", age: 21}
{# name: "Lars Connelly", favoriteColor: "White", age: 21}
{# name: "Kirk Jones", favoriteColor: "Orange", age: 22}
The most common favorite color is:
White
Persons with the most common favorite color is:
Kirk Comer
Joe Connelly
Steven Lawrence
James Johanson
Brad Dench
Lars Lawrence
Brad Hayek
Robert Comer
Lars Hayek
Robert Lawrence
Lars Dench
Lars Connelly
*/
.namespace and .filenamespace directives you can now use the 3 notations:
.filenamespace system.lib._8bit
.namespace .. { }
.namespace @tetris.func { }.filenamespace starts from the root only relative namespace paths makes sence for this directive.
.macro script.MyMacro() { ... }
.pseudocommand lib.pseudo.mypseudo arg { ... }
.function ..function(x,y,z) { ... }
.segment @segments.Code [start=$5000]
.macro ...AnotherMacro() { ... }
.macro @MyRootMacro() { ... }
.function @func.myRootRelFunction(x,y,z) { ... }
.macro @lib.MyLibMacro() { ... }
.namespace visible.space {
.label x = 1
}
.namespace definition.space {
.label x = 2
.macro @visible.space.PrintX() {
.print x
}
}
visible.space.PrintX() // This will print 2script.MyMacro() lib.pseudo.mypseudo #27 .segment @segments.Code .eval lib.funcs.myFunction(x,y) @MyRootMacro() .file [name="Data1.prg", segments="@files.File1"] @lib.MyLibMacro()
.namespace one.two.three.four.five {
.macro MyMacro() {}
// This will go 3 levels back and find 'three' and then follow the path back to five and find the macro
three.four.five.MyMacro()
}
.segmemtmodifier directive to make segment modifiers.The auto included segment value contains:
.segmentmodifier Print() {
// Print segment data
.printnow "segment.name= "+segment.name
.printnow "segment.dest= "+segment.dest
.foreach (block in segment.getBlocks()) {
// Print block data
.printnow "block.name= "+block.name
.printnow "block.start= "+block.start
.printnow "block.end= "+block.end
.printnow "block.bytes.size()= "+block.bytes.size()
// Return the block unchanged
*=block.start
.fill block.bytes
}
}
.segment TestSegment [modify="Print", dest="x"]
*=$1000 "This is block 1"
.byte 1,2,3
.memblock "This is block 2"
.byte 1,2
*=$2000 "This is block 3"
.fill $100, i
.segmentmodifier DeltaPack() {
.var block = segment.flattenBlocks()
.var lastB = 0
*=block.start
.foreach(b in block.bytes) {
.byte b - lastB
.eval lastB = b
}
}
.segmentmodifier SimplePack(_start) {
*=_start
.var blocks = segment.mergeConnectedBlocks()
.byte blocks.size()
.foreach (block in blocks) {
.word block.start
.word block.bytes.size()
.fill block.bytes
}
}