ozanh/ugodev

View on GitHub
playground/cmd/wasm/testdata/sample.ugo

Summary

Maintainability
Test Coverage
/*
  uGO Language
*/

a := 1      // int
b := 2u     // uint
c := 'c'    // char
d := "text" // string
e := 3.14   // float

// compiled-function
const fn = func(v) {
  strings := import("strings")
  if strings.ToLower(v) != "ugo" {
    return "", error("wrong argument")
  }
  return strings.Join([v, "Playground"], " ")
}

var g = false               // bool
h := error("error message") // error

println("a:", a, "b:", b, "c:", c, "d:", d,
  "e:", e, "f:", fn, "g:", "h:", h)

u, err := fn("uGO")
if err != undefined {
  throw err
}
println(u)

// arrays

arr := [a, b, c, d]
arr = append(arr, e)

for i, v in arr {
    printf("arr[%d]=%+v\n", i, v)
}
/*
for v in arr {
    println(v)
}
*/

// slicing
var (
    s1 = arr[:2]
    s2 = arr[2:]
)
println("s1:", s1, "\ns2:", s2)
println("hello world"[1:5])

// sum given numbers
const sum = func(...nums) {
    var total = 0
    for i, v in nums {
      total += nums[i]
    }
    return total
  }

nums := [1, 2, 3, 4, 5, 6]
println(sum(...nums))  // expand array
println(len(nums))     // length of array

// destructuring array
n1, n2 := nums
println(n1, n2)  // n1 == nums[0], n2 == nums[1]

// destructuring array
nums, err = func(nums) {
  if len(nums) != 10 {
    return undefined, error("array length must be 10")
  }
}(nums)
println(nums, err)  // nums == undefined, err = error("array length must be 10")
 
var count_evens
count_evens = func(n, c) {
  if n == 0 {
    return c
  } else if n % 2 == 0 {
    c++
  }
  return count_evens(n-1, c)
}

num_evens := count_evens(1984, 0)
println(num_evens)

// type coercion
v1 := string(2018)    // "2018"
v2 := int("2018")     // 2018
v3 := int("0b101")    // 5
v4 := float(-7)       // -7.0
v5 := char(65)        // 'A'
v6 := bool("abc")     // true

func(...args) {
  arr := repeat([undefined], len(args))
  for i,v in args {
    arr[i] = sprintf("%s:%v", typeName(v), v)
  }
  println(arr)
}(v1, v2, v3, v4, v5, v6)

// ternary operator
v7 := v2 > v3 ? v2 << 1 : v2 >> 1
println(v7)

// calculate fibonacci number
var fib
fib = func(x) { return x <= 1 ? x : fib(x-1) + fib(x-2) }
println("fibonacci(6)=>", fib(6))

// create a map
m := {
      a: 1, b: 2.0, c: string(v7),
      fn: func(x) { return x+1 },
     }

// use .key or ["key"] notations to access keys
m.test = "test"
m["test"] = "test"
println(m)

// invalid map index returns undefined
if m.invalid == undefined {
  println("OK")
}

// undefined values' indexes are undefined
println(undefined.x.y)

// get map index and call
println(m.fn(10))

// map iterations are randomized
// iterate map and append map key and value to an array
arr = []
for k, v in m {
  printf("key:%s value:%v\n", k, v)
  arr = append(arr, k, v)
}
println(arr)

// import stdlib fmt module
fmt := import("fmt")
// import stdlib strings module
strings := import("strings")
// import stdlib time module
time := import("time")

// scan arguments
arg1 := fmt.ScanArg("string")
arg2 := fmt.ScanArg("int")
r := fmt.Sscanf("abc 123", "%s%d", arg1, arg2)
// this is printed to your browser console
fmt.Println("n:", r, arg1.Value, arg2.Value)

// add 1 hour to now and print with RFC3339Nano layout
// this is printed to your browser console
fmt.Println(time.Format(time.Now() + time.Hour, time.RFC3339Nano))

// string padding
s := strings.PadLeft(string(int("1_984")), 8, "=>")
s = strings.PadRight(s, 12, "<=")
println(s,
        sprintf("\n  has %d '=>' and %d '<='",
        strings.Count(s, "=>"),
        strings.Count(s, "<=")),
)

// import json module
json := import("json")
printf("json: %s\n", json.Marshal({a:10, b:undefined}))


// Error Handling

// 1. Return error as a value
v := func(...args) {
  return len(args) > 0 ? args[0] : error("error encountered")
}()

if isError(v) {
  println(v)
}

// 2. try-catch-finally
try {
  func() {
    throw "thrown error"
  }()
} catch err {
  println("caught:", err.Message)
} finally {
  // this block is always executed
  println("finally block")
}

// thrown errors hold stack traces
v = func() {
  throw "with stack trace"
}

try {
  v()
} catch err {
  printf("%+v\n", err)
}

// some examples
v = 0
for i := 0; i < 100; i++ {
  try {
    continue
  } finally {
    v++
    i++
  }
}
println(v)  // 50

/*******************************/
v = 0
for i := 0; i < 100; i++ {
  try {
    break
  } finally {
    v++
  }
}
println(v)  // 1

/*******************************/
v = 0
for i := 0; i < 100; i++ {
  try {
    i  / v  // zero divison error
  } catch err {
    printf("%+v\n", err)
    break
  } finally {
    v++
  }
}
println(v)  // 1

/*******************************/
try {
  v := func() {
    try {
      err := error("message")
      throw err
    } finally {
      return "ignore thrown error"
    }
  }()
} catch err {
  println(err)
} finally {
  println(v)
}

return "End"