Browse Source

Go language support

stepan-mitkin 3 years ago
parent
commit
3b4d82224f

BIN
examples/C#/Demo.drn


BIN
examples/C#/Sorter.drn


BIN
examples/Go/go_demo.drn


+ 566 - 0
examples/Go/go_demo.go

@@ -0,0 +1,566 @@
+// Autogenerated with DRAKON Editor 1.27
+
+package main
+
+import (
+	"fmt"
+)
+
+type Var int
+
+type Objects []interface{}
+type Comparator func(interface{}, interface{}) int
+
+
+
+func  Fibonacci(n int) []int {
+    // item 300
+    result := []int{0}
+    // item 2860001
+    if n == 0 {
+        
+    } else {
+        // item 2860002
+        if n == 1 {
+            // item 301
+            result = append(result, 1)
+        } else {
+            // item 304
+            result = append(result, 1)
+            // item 303
+            f0 := 0
+            f1 := 1
+            // item 2930001
+            i := 2;
+            for {
+                // item 2930002
+                if i <= n {
+                    
+                } else {
+                    break
+                }
+                // item 294
+                fib := f0 + f1
+                f0, f1 = f1, fib
+                // item 305
+                result = append(result, fib)
+                // item 2930003
+                i++;
+            }
+        }
+    }
+    // item 298
+    return result
+}
+
+func  Quicksort(comparer Comparator, collection Objects, begin int, end int)  {
+    // item 405
+    length := end - begin
+    last := end - 1
+    // item 4060001
+    if (length == 0) || (length == 1) {
+        
+    } else {
+        // item 4060003
+        if length == 2 {
+            // item 421
+            if compare(comparer, collection, begin, last) <= 0 {
+                
+            } else {
+                // item 422
+                swap(collection, begin, last)
+            }
+        } else {
+            // item 425
+            pivotIndex := begin + length / 2
+            // item 433
+            swap(collection, pivotIndex, last)
+            storeIndex := begin
+            // item 4260001
+            i := begin;
+            for {
+                // item 4260002
+                if i < last {
+                    
+                } else {
+                    break
+                }
+                // item 434
+                if compare(comparer, collection, i, last) < 0 {
+                    // item 435
+                    swap(collection, i, storeIndex)
+                    storeIndex++
+                } else {
+                    
+                }
+                // item 4260003
+                i++;
+            }
+            // item 438
+            swap(collection, storeIndex, last)
+            // item 439
+            Quicksort(comparer, collection, begin, storeIndex)
+            // item 440
+            Quicksort(comparer, collection, storeIndex + 1, end)
+        }
+    }
+}
+
+func  Sort(list Objects, comparer Comparator)  {
+    // item 373
+    Quicksort(comparer, list, 0, len(list))
+}
+
+func  assertEqual(a int, b int)  {
+    // item 175
+    if a == b {
+        
+    } else {
+        // item 178
+        panic("assert failed")
+    }
+}
+
+func  columnNN(nna bool, nnb bool) int {
+    // item 181
+    var nnm int
+    // item 125
+    if (nna) || (nnb) {
+        // item 130
+        nnm = 2
+    } else {
+        // item 129
+        nnm = 1
+    }
+    // item 133
+    return nnm
+}
+
+func  columnNY(nya bool, nyb bool) int {
+    // item 182
+    var nym int
+    // item 113
+    if (nya) || (!(nyb)) {
+        // item 118
+        nym = 2
+    } else {
+        // item 117
+        nym = 1
+    }
+    // item 121
+    return nym
+}
+
+func  columnYN(yna bool, ynb bool) int {
+    // item 183
+    var ynm int
+    // item 101
+    if (yna) && (!(ynb)) {
+        // item 105
+        ynm = 1
+    } else {
+        // item 106
+        ynm = 2
+    }
+    // item 109
+    return ynm
+}
+
+func  columnYY(yya bool, yyb bool) int {
+    // item 184
+    var yym int
+    // item 47
+    if (yya) && (yyb) {
+        // item 51
+        yym = 1
+    } else {
+        // item 52
+        yym = 2
+    }
+    // item 55
+    return yym
+}
+
+func  compare(comparer Comparator, array Objects, a int, b int) int {
+    // item 457
+    left := array[a]
+    right := array[b]
+    // item 458
+    return comparer(left, right)
+}
+
+func  complex1(x1 bool, x2 bool, x3 bool, x4 bool) int {
+    // item 137
+    if ((x1) && (!(x2))) || (!((x3) || (!(x4)))) {
+        // item 143
+        return 1
+    } else {
+        // item 148
+        return 2
+    }
+}
+
+func  complex2(x1 bool, x2 bool, x3 bool, x4 bool) int {
+    // item 152
+    if ((x1) || (!(x2))) && (!((x3) && (!(x4)))) {
+        // item 158
+        return 1
+    } else {
+        // item 163
+        return 2
+    }
+}
+
+func  foreachDemo()  {
+    // item 235
+    fmt.Println("Iteration demo")
+    // item 233
+    var sequence []int = Fibonacci(15)
+    // item 234
+    printListArrow(sequence)
+    printListFor(sequence)
+    printListForeach(sequence)
+    // item 236
+    fmt.Println("")
+    // item 239
+    testEarly(20, 60)
+    // item 240
+    testEarly(35, 70)
+    // item 241
+    testEarly(4, 0)
+}
+
+func  foreachEarlyExit(value int) int {
+    // item 270
+    found := -1
+    var normal_254 int
+    normal_254 = 1
+    for _, x := range []int{10, 20, 30} {
+        // item 258
+        if x == value {
+            // item 262
+            found = x
+            normal_254 = 0
+            break
+        } else {
+            
+        }
+    }
+    if normal_254 == 1 {
+        // item 261
+        found = 0
+    }
+    for _, x := range []int{40, 20, 70} {
+        // item 269
+        m := x / 2
+        // item 264
+        if m == value {
+            // item 268
+            return x + found
+        } else {
+            
+        }
+    }
+    // item 267
+    return 0
+}
+
+func  main()  {
+    // item 180
+    testShortCircuit()
+    // item 307
+    foreachDemo()
+    // item 318
+    fmt.Println("Method demo")
+    // item 27
+    x := Var(20)
+    y := x.printAdd(5)
+    
+    fmt.Println(y)
+    // item 320
+    fmt.Println("")
+    // item 459
+    quicksortDemo()
+}
+
+func  print(collection Objects)  {
+    for _, item := range collection {
+        // item 366
+        fmt.Printf("%s ", item)
+    }
+    // item 374
+    fmt.Println("")
+}
+
+func (self Var) printAdd(value int) Var {
+    // item 314
+    newValue := int(self) + value
+    // item 316
+    fmt.Printf("%d -> %d\n", int(self), newValue)
+    // item 315
+    return Var(newValue)
+}
+
+func  printListArrow(collection []int)  {
+    // item 211
+    fmt.Println("using if and arrow:")
+    // item 206
+    length := len(collection)
+    i := 0
+    for {
+        // item 207
+        if i < length {
+            
+        } else {
+            break
+        }
+        // item 205
+        item := collection[i]
+        write(item)
+        // item 209
+        i++
+    }
+    // item 212
+    fmt.Println("")
+}
+
+func  printListFor(collection []int)  {
+    // item 219
+    fmt.Println("using for:")
+    // item 223
+    length := len(collection)
+    // item 2170001
+    i := 0;
+    for {
+        // item 2170002
+        if i < length {
+            
+        } else {
+            break
+        }
+        // item 222
+        write(collection[i])
+        // item 2170003
+        i++;
+    }
+    // item 220
+    fmt.Println("")
+}
+
+func  printListForeach(collection []int)  {
+    // item 198
+    fmt.Println("using foreach:")
+    for key, value := range collection {
+        // item 195
+        fmt.Printf("%d->%d ", key, value)
+    }
+    // item 197
+    fmt.Println("")
+}
+
+func  quicksortDemo()  {
+    // item 328
+    fmt.Println("quick sort demo")
+    // item 324
+     unsorted := Objects { "the", "sooner", "we", "start", "this", "the", "better" }
+     sorted   := Objects { "aa", "bb", "cc", "dd", "ee", "ff" }
+     reverse  := Objects { "ff", "ee", "dd", "cc", "bb", "aa" }
+     empty    := Objects {}
+     flat     := Objects { "flat", "flat", "flat", "flat", "flat" }
+    // item 325
+    comparer := reverseStringComparer
+    // item 332
+    Sort(unsorted, comparer)
+    Sort(sorted, comparer)
+    Sort(reverse, comparer)
+    Sort(empty, comparer)
+    Sort(flat, comparer)
+    // item 326
+    print(unsorted)
+    print(sorted)
+    print(reverse)
+    print(empty)
+    print(flat)
+    // item 327
+    stringsAreSorted(unsorted)
+    stringsAreSorted(sorted)
+    stringsAreSorted(reverse)
+    stringsAreSorted(empty)
+    stringsAreSorted(flat)
+    // item 331
+    fmt.Println()
+}
+
+func  reverseStringComparer(left interface{}, right interface{}) int {
+    // item 380
+    ls := left.(string)
+    rs := right.(string)
+    // item 3810001
+    if ls < rs {
+        // item 391
+        return 1
+    } else {
+        // item 3810002
+        if ls == rs {
+            // item 390
+            return 0
+        } else {
+            // item 388
+            return -1
+        }
+    }
+}
+
+func  stairsNN(nnas bool, nnbs bool) int {
+    // item 185
+    var nnms int
+    // item 87
+    if (nnas) && (nnbs) {
+        // item 94
+        nnms = 2
+    } else {
+        // item 93
+        nnms = 1
+    }
+    // item 97
+    return nnms
+}
+
+func  stairsNY(nyas bool, nybs bool) int {
+    // item 186
+    var nyms int
+    // item 73
+    if (nyas) && (!(nybs)) {
+        // item 80
+        nyms = 2
+    } else {
+        // item 79
+        nyms = 1
+    }
+    // item 83
+    return nyms
+}
+
+func  stairsYN(ynas bool, ynbs bool) int {
+    // item 187
+    var ynms int
+    // item 59
+    if (ynas) || (!(ynbs)) {
+        // item 65
+        ynms = 1
+    } else {
+        // item 66
+        ynms = 2
+    }
+    // item 69
+    return ynms
+}
+
+func  stairsYY(yyas bool, yybs bool) int {
+    // item 188
+    var yyms int
+    // item 33
+    if (yyas) || (yybs) {
+        // item 39
+        yyms = 1
+    } else {
+        // item 40
+        yyms = 2
+    }
+    // item 43
+    return yyms
+}
+
+func  stringsAreSorted(array Objects)  {
+    // item 3380001
+    i := 1;
+    for {
+        // item 3380002
+        if i < len(array) {
+            
+        } else {
+            break
+        }
+        // item 358
+        before := array[i - 1].(string)
+        current := array[i].(string)
+        // item 448
+        if before < current {
+            // item 451
+            panic("strings are not sorted")
+            break
+        } else {
+            
+        }
+        // item 3380003
+        i++;
+    }
+}
+
+func  swap(array Objects, leftIndex int, rightIndex int)  {
+    // item 447
+    left := array[leftIndex];
+    right := array[rightIndex];
+    // item 446
+    array[leftIndex] = right
+    array[rightIndex ] = left
+}
+
+func  testEarly(value int, expected int)  {
+    // item 277
+    var actual int = foreachEarlyExit(value)
+    // item 278
+    if actual == expected {
+        
+    } else {
+        // item 281
+        panic("foreach_early_exit failed")
+    }
+}
+
+func  testShortCircuit()  {
+    // item 308
+    fmt.Println("Short-circuit test")
+    // item 179
+    assertEqual(columnNN(false, false), 1)
+    assertEqual(columnNN(false, true ), 2)
+    assertEqual(columnNN(true,  false), 2)
+    assertEqual(columnNN(true,  true ), 2)
+    assertEqual(columnNY(false, false), 2)
+    assertEqual(columnNY(false, true ), 1)
+    assertEqual(columnNY(true,  false), 2)
+    assertEqual(columnNY(true,  true ), 2)
+    assertEqual(columnYN(false, false), 2)
+    assertEqual(columnYN(false, true ), 2)
+    assertEqual(columnYN(true,  false), 1)
+    assertEqual(columnYN(true,  true ), 2)
+    assertEqual(columnYY(false, false), 2)
+    assertEqual(columnYY(false, true ), 2)
+    assertEqual(columnYY(true,  false), 2)
+    assertEqual(columnYY(true,  true ), 1)
+    assertEqual(stairsNN(false, false), 1)
+    assertEqual(stairsNN(false, true ), 1)
+    assertEqual(stairsNN(true,  false), 1)
+    assertEqual(stairsNN(true,  true ), 2)
+    assertEqual(stairsNY(false, false), 1)
+    assertEqual(stairsNY(false, true ), 1)
+    assertEqual(stairsNY(true,  false), 2)
+    assertEqual(stairsNY(true,  true ), 1)
+    assertEqual(stairsYN(false, false), 1)
+    assertEqual(stairsYN(false, true ), 2)
+    assertEqual(stairsYN(true,  false), 1)
+    assertEqual(stairsYN(true,  true ), 1)
+    assertEqual(stairsYY(false, false), 2)
+    assertEqual(stairsYY(false, true ), 1)
+    assertEqual(stairsYY(true,  false), 1)
+    assertEqual(stairsYY(true,  true ), 1)
+    // item 319
+    fmt.Println("")
+}
+
+func  write(item int)  {
+    // item 229
+    fmt.Printf("%d ", item)
+}
+
+// I am the footer.

BIN
examples/Python/short_circuit.drn


+ 1 - 1
generators/d.tcl

@@ -371,7 +371,7 @@ proc or { left right } {
 }
 
 # NOT logical operator
-proc p.not { operand } {
+proc not { operand } {
     #item 633
     return "!\($operand\)"
 }

+ 375 - 0
generators/go.tcl

@@ -0,0 +1,375 @@
+gen::add_generator "Go" gen_go::generate
+
+namespace eval gen_go {
+
+# These keywords can be used in function headers.
+variable keywords {
+    break        default      func         interface    select
+    case         defer        go           map          struct
+    chan         else         goto         package      switch
+    const        fallthrough  if           range        type
+    continue     for          import       return       var
+	bool string
+	int uint
+	int8 int16 int32 int64
+	uint8 uint16 uint32 uint64
+	float32 float64
+	complex64 complex128
+	byte rune uintptr
+	true false
+	nil
+	len cap
+}
+
+
+# An optional procedure for syntax highlighting
+proc highlight { tokens } {
+	variable keywords
+	return [ gen_cs::highlight_generic $keywords $tokens ]
+}
+
+# The code generator procedure. It will be called by DRAKON Editor.
+# Arguments:
+#   db - A handle to the database of the original file. Read only!
+#   gdb - A handle to the temporary database. Read-write.
+#   filename - The .drn filename.
+proc generate { db gdb filename } {
+	global errorInfo
+	
+	# Construct the callbacks dictionary
+	set callbacks [ make_callbacks ]
+
+	# Extract sections from the file descriptions
+	lassign [ gen::scan_file_description $db { header footer } ] header footer
+
+	# Get the list of diagrams
+	set diagrams [ $gdb eval {
+		select diagram_id from diagrams } ]
+		
+	# Select only DRAKON diagrams and pre-process them.
+	foreach diagram_id $diagrams {
+		if { [ mwc::is_drakon $diagram_id ] } {
+			set append_semicolon 1
+			gen::fix_graph_for_diagram $gdb $callbacks $append_semicolon $diagram_id
+		}
+	}
+	
+	# Do the code generation
+	set nogoto 1
+	set functions [ gen::generate_functions \
+		$db $gdb $callbacks $nogoto ]
+
+	# Abort if any errors happened so far.
+	if { [ graph::errors_occured ] } { return }
+
+	set hfile [ replace_extension $filename "go" ]
+	
+	# Open the output file and write the code.
+	set f [ open $hfile w ]
+	catch {
+		print_to_file $f $functions $header $footer
+	} error_message
+	set savedInfo $errorInfo
+	
+	# Close the file regardless of exceptions.	
+	catch { close $f }
+	if { $error_message != "" } {
+		puts $errorInfo
+		# Rethrow the exception
+		error $error_message savedInfo
+	}
+}
+
+# Builds a collection of code snippet generators specific to the Go language.
+proc make_callbacks { } {
+	set callbacks {}
+
+	gen::put_callback callbacks assign			gen_go::assign
+	gen::put_callback callbacks compare			gen_go::compare
+	gen::put_callback callbacks compare2		gen_go::compare
+	gen::put_callback callbacks while_start 	gen_go::while_start
+	gen::put_callback callbacks if_start		gen_go::if_start
+	gen::put_callback callbacks elseif_start	gen_go::elseif_start
+	gen::put_callback callbacks if_end			gen_go::if_end
+	gen::put_callback callbacks else_start		gen_go::else_start
+	gen::put_callback callbacks pass			gen_go::pass
+	gen::put_callback callbacks return_none		gen_go::return_none
+	gen::put_callback callbacks block_close		gen_go::block_close
+	gen::put_callback callbacks comment			gen_go::comment
+	gen::put_callback callbacks bad_case		gen_go::bad_case
+	gen::put_callback callbacks for_declare		gen_go::foreach_declare	
+	gen::put_callback callbacks for_init		gen_go::foreach_init
+	gen::put_callback callbacks for_check		gen_go::foreach_check
+	gen::put_callback callbacks for_current		gen_go::foreach_current
+	gen::put_callback callbacks for_incr		gen_go::foreach_incr
+	gen::put_callback callbacks and				gen_go::and
+	gen::put_callback callbacks or				gen_go::or
+	gen::put_callback callbacks not				gen_go::not
+	gen::put_callback callbacks break			"break"
+	gen::put_callback callbacks declare			gen_go::declare
+	gen::put_callback callbacks shelf			gen_go::shelf
+				
+	gen::put_callback callbacks body			gen_go::generate_body
+	gen::put_callback callbacks signature		gen_go::extract_signature
+	gen::put_callback callbacks native_foreach	gen_go::native_foreach
+
+	return $callbacks
+}
+
+# A simple variable assignment.
+proc assign { variable value } {
+	return "$variable = $value"
+}
+
+# A comparison of two values.
+proc compare { variable constant } {
+	return "$variable == $constant"
+}
+
+# The beginning of an eternal __while__ loop.
+proc while_start { } {
+	return "for \{"
+}
+
+# The left part of an __if__ condition
+proc if_start { } {
+	return "if "
+}
+
+# slse if expression
+proc elseif_start { } {
+    return "\} else if "
+}
+
+# The right part of __if__ condition
+proc if_end { } {
+    return " \{"
+}
+
+# else expression
+proc else_start { } {
+    return "\} else \{"
+}
+
+# Empty expression.
+proc pass { } {
+    return ""
+}
+
+# Early exit from a function
+proc return_none { } {
+    return "return"
+}
+
+# End of a block.
+# Appends a line with an indented closing curly to the output.
+proc block_close { output depth } {
+    upvar 1 $output result
+    set line [ gen::make_indent $depth ]
+    append line "\}"
+    lappend result $line
+}
+
+# A one-line comment.
+proc comment { line } {
+    return "// $line"
+}
+
+# Raises an error when the control reaches an unexpected "case" branch.
+proc bad_case { switch_var select_icon_number } {
+    if {[ string compare -nocase $switch_var "select" ] == 0} {
+    	return "panic\(\"Not expected condition.\"\)"
+    } else {	
+		return "panic\(\"Not expected $switch_var\"\)"
+	}
+}
+
+proc native_foreach { for_it for_var } {
+	return "for $for_it := range $for_var \{"
+}
+
+# Declares the iterator and/or the iterated variable.
+# We don't need this in D.
+proc foreach_declare { item_id first second } {
+    return ""
+}
+
+# Initialises the iterator.
+# With D, we declare and init a range.
+proc foreach_init { item_id first second } {
+	return ""
+}
+
+# Checks whether it is time to exit the iteration. 
+proc foreach_check { item_id first second } {
+	return ""
+}
+
+# Gets the current element from the iterator.
+proc foreach_current { item_id first second } {
+	return ""
+}
+
+# Advances the iterator.
+proc foreach_incr { item_id first second } {
+    #item 32
+    return ""
+}
+
+# AND logical operator
+proc and { left right } {
+    return "($left) && ($right)"
+}
+
+# OR logical operator
+proc or { left right } {
+    return "($left) || ($right)"
+}
+
+# NOT logical operator
+proc not { operand } {
+    #item 633
+    return "!\($operand\)"
+}
+
+# Declares and inits a variable
+proc declare { type name value } {
+    if { $value == "" } {
+        return "var $name $type"
+    } else {
+        return "$name := $value"
+    }
+}
+
+# Builds code for a __shelf__ icon.
+proc shelf { primary secondary } {
+    return "$secondary = $primary"
+}
+
+# DRAKON Editor could not generate a body for the function.
+# The code generation failed.
+# Probably, the algorithm is too complex for the generator.
+# The plugin is supposed to fix this.
+# We resort to the loop generator that always works, but is quite slow.
+proc generate_body { gdb diagram_id start_item node_list items incoming } {
+	set name [ $gdb onecolumn {
+		select name from diagrams where diagram_id = :diagram_id
+	} ]
+	error "Diagram $name is too complex"
+}
+
+# Remove comments
+# Drop empty lines.
+proc drop_empty_lines { pairs } {
+	set result {}
+	foreach pair $pairs {
+		lassign $pair code comment
+		if { $code != {} } {
+			lappend result $pair
+		}
+	}
+	return $result
+}
+
+# Gets the return type and arguments.
+proc get_return_type_and_arguments { pairs } {
+	if { $pairs == {} } {
+		set arguments {}
+		set returns ""
+	} else {
+		set last [ lindex $pairs end ]
+		set start [ lindex $last 0 ]
+		if { [ string match "returns *" $start ] } {
+			set arguments [ lrange $pairs 0 end-1]
+			set returns [ gen_cpp::extract_return_type $start ]
+		} else {
+			set arguments $pairs
+			set returns ""
+		}
+	}
+	
+	return [ list $returns $arguments ]
+}
+
+
+# This callback generates a signature given the text of the "formal parameters" icon.
+# (An optional icon that sits to the right from the diagram header.)
+# Here, we just build a simple signature that consists of:
+# - arguments
+# - return value
+# f. ex. int Foo(int a, string b)
+proc extract_signature { text name } {
+	# Separate code from comments that start with //
+	set pairs_raw [ gen::separate_from_comments $text ]
+	# Get only meaningful lines.
+	set pairs [ drop_empty_lines $pairs_raw ]
+
+	lassign [ get_return_type_and_arguments $pairs ] returns parameters
+	
+
+	
+	set type "procedure"
+    set signature [ gen::create_signature $type {} $parameters $returns ]
+
+	# No errors occurred.
+	set error_message ""
+    return [ list $error_message $signature ]
+}
+
+# Writes everything to the output file.
+proc print_to_file { fhandle functions header footer } {
+	# Print the proud banner first.
+	set version [ version_string ]
+	puts $fhandle \
+	    "// Autogenerated with DRAKON Editor $version"
+
+
+	puts $fhandle ""
+	puts $fhandle $header
+	puts $fhandle ""
+	# Print the functions, one by one.
+	foreach function $functions {
+		lassign $function diagram_id name signature body
+		puts $fhandle ""
+		set declaration [ build_declaration $name $signature ]
+		puts $fhandle $declaration
+		set lines [ gen::indent $body 1 ]
+		puts $fhandle $lines
+		puts $fhandle "\}"
+	}
+	puts $fhandle ""
+	puts $fhandle $footer
+}
+
+# Builds the header of a function.
+proc build_declaration { name signature } {
+	lassign $signature type access parameters returns
+	
+	if { $parameters == {} } {
+	
+        set params2 ""
+        set self ""
+    } else {
+        set first_line [ lindex $parameters 0 ]
+        set first [ lindex $first_line 0 ]
+        set first_name [ lindex $first 0 ]
+        if { $first_name == "self" } {
+            set params2 [ lrange $parameters 1 end ]
+            set self "\($first\)"
+        } else {
+            set params2 $parameters
+            set self ""
+        }
+    }
+	
+	set result "func $self $name\("
+	set params {}
+	foreach parameter $params2 {
+		lappend params [ lindex $parameter 0 ]
+	}
+	append result [ join $params ", " ]
+	return "$result\) $returns \{"
+}
+
+
+}

BIN
generators/python.drn


+ 1 - 0
generators/python.tcl

@@ -13,6 +13,7 @@ break     except    import    print
 class     exec      in        raise
 continue  finally   is        return 
 def       for       lambda    try
+True      False
 }
 
 # Autogenerated with DRAKON Editor 1.27

+ 2 - 2
make_mac_release.sh

@@ -5,6 +5,6 @@ cd release
 cp -r ../DRAKONEditor/build/Release/DRAKONEditor.app .
 cp -r ../examples .
 cp ../readme_mac.html readme.html
-zip -r ../drakon_editor1.26_mac.zip *
+zip -r ../drakon_editor1.27_mac.zip *
 cd ..
-rm -rf release
+rm -rf release

+ 2 - 2
make_release.sh

@@ -16,6 +16,6 @@ mkdir tmp
 cp ../drakon_editor.tcl .
 cp ../drakon_gen.tcl .
 cp ../readme.html .
-zip -r ../drakon_editor1.26.zip *
+zip -r ../drakon_editor1.27.zip *
 cd ..
-rm -rf release
+rm -rf release

+ 2 - 2
make_release_rus.sh

@@ -17,6 +17,6 @@ mkdir tmp
 cp ../drakon_editor.tcl .
 cp ../drakon_gen.tcl .
 cp ../readme.html .
-zip -r ../drakon_editor1.26_rus.zip *
+zip -r ../drakon_editor1.27_rus.zip *
 cd ..
-rm -rf release
+rm -rf release

+ 14 - 3
readme.html

@@ -1,12 +1,12 @@
 <html>
 <header>
-        <title>DRAKON Editor v.1.26 Readme</title>
+        <title>DRAKON Editor v.1.27 Readme</title>
         <style>
             body { width: 800px; }
         </style>
 </header>
 <body>
-<h1><img src="images/drakon_editor.gif" alt="Logo"/>DRAKON Editor 1.26</h1>
+<h1><img src="images/drakon_editor.gif" alt="Logo"/>DRAKON Editor 1.27</h1>
 <p><b>DRAKON helps people understand programs.</b></p>
 
 
@@ -158,6 +158,17 @@
 <p>Your feedback is greatly appreciated. Please write to<br/>
 <b>drakon.editor@gmail.com</b></p>
 
+<h2>What's new in version 1.27</h2>
+<ul>
+<li><a href="https://golang.org/">Go language</a> support.</li>
+<li>Nice <strong>foreach</strong> code generation for Java, C#, Python, Tcl, Lua, D.</li>
+<li>Better boolean short-circuit detection.</li>
+<li>C/C++ code generator does not generate redundant <strong>return</strong> statements anymore.</li>
+<li>Erlang generator does not emit <strong>throw</strong> when no default clause is present in a <strong>select</strong> statement.</li>
+<li>JavaScript code generator: different <strong>foreach</strong> for objects and arrays.</li>
+<li>Stricter handling of <strong>select</strong> keyword inside <strong>select</strong> icon.</li>
+</ul>
+
 <h2>What's new in version 1.26</h2>
 <ul>
 <li>Massive improvements to the Erlang code generator: <strong>receive</strong> statement, <strong>select/case</strong> macroicon produces "case X of" statement, visual supervision tree.</li>
@@ -361,6 +372,6 @@
 <p>Stepan Mitkin, Alexander Ilyin, Maas-Maarten Zeeman, Vasil Dyadov, Vasili Bachiashvili.</p>
 <p><a href="http://drakon-editor.sourceforge.net/">http://drakon-editor.sourceforge.net/</a></p>
 <p><b>drakon.editor@gmail.com</b></p>
-<p>1 June 2015.</p>
+<p>10 March 2016.</p>
 </body>
 </html>

+ 14 - 3
readme_mac.html

@@ -1,12 +1,12 @@
 <html>
 <header>
-        <title>DRAKON Editor v.1.26 Readme</title>
+        <title>DRAKON Editor v.1.27 Readme</title>
         <style>
             body { width: 800px; }
         </style>
 </header>
 <body>
-<h1>DRAKON Editor 1.26</h1>
+<h1>DRAKON Editor 1.27</h1>
 <p><b>DRAKON helps people understand programs.</b></p>
 
 
@@ -135,6 +135,17 @@
 <p>Your feedback is greatly appreciated. Please write to<br/>
 <b>drakon.editor@gmail.com</b></p>
 
+<h2>What's new in version 1.27</h2>
+<ul>
+<li><a href="https://golang.org/">Go language</a> support.</li>
+<li>Nice <strong>foreach</strong> code generation for Java, C#, Python, Tcl, Lua, D.</li>
+<li>Better boolean short-circuit detection.</li>
+<li>C/C++ code generator does not generate redundant <strong>return</strong> statements anymore.</li>
+<li>Erlang generator does not emit <strong>throw</strong> when no default clause is present in a <strong>select</strong> statement.</li>
+<li>JavaScript code generator: different <strong>foreach</strong> for objects and arrays.</li>
+<li>Stricter handling of <strong>select</strong> keyword inside <strong>select</strong> icon.</li>
+</ul>
+
 <h2>What's new in version 1.26</h2>
 <ul>
 <li>Massive improvements to the Erlang code generator: <strong>receive</strong> statement, <strong>select/case</strong> macroicon produces "case X of" statement, visual supervision tree.</li>
@@ -342,6 +353,6 @@
 <p>Stepan Mitkin, Alexander Ilyin, Maas-Maarten Zeeman, Vasil Dyadov, Vasili Bachiashvili.</p>
 <p><a href="http://drakon-editor.sourceforge.net/">http://drakon-editor.sourceforge.net/</a></p>
 <p><b>drakon.editor@gmail.com</b></p>
-<p>1 June 2014.</p>
+<p>10 March 2016.</p>
 </body>
 </html>

+ 1 - 1
scripts/version.tcl

@@ -12,5 +12,5 @@ proc version_string { } {
 }
 
 proc version_tag { } {
-	return "dev"
+	return "RC1"
 }