← nimrepo

more nims

1e19d7bb51d70362c166d234f9abd3e83c0222ac · ovidiucs · Jan 29, 2019 10:56

+732 · 11 files changed

  • acroexample.nim +41 −0
  • arrays.nim +328 −0
  • fsm.nim +18 −0
  • getalphabet.nim +49 −0
  • hslice.nim +37 −0
  • macros2.nim +62 −0
  • nimboxtest.nim +15 −0
  • stackpollute.nim +10 −0
  • stuff.nim +119 −0
  • trmacros.nim +26 −0
  • variables.nim +27 −0
diff --git a/acroexample.nim b/acroexample.nim
new file mode 100644
index 0000000..ea927d3
--- /dev/null
+++ b/acroexample.nim
@@ -0,0 +1,41 @@
+import macros
+
+
+echo " text style expression macro "
+
+macro gen_hello(): typed =
+  let source = """
+proc hello() =
+  echo "hi"
+"""
+  result = parseStmt(source)
+
+gen_hello()
+hello()
+
+echo """
+The macro is defined like a procedure except you use “macro” instead of “proc”.
+The result is the AST you want to insert at the point the macro is called.
+The parseStmt converts the string to AST. The “hello()” call calls the hello procedure generated by the macro.
+"""
+
+
+echo """ same expression macro in AST style."""
+
+
+dumpTree:
+  proc hello() =
+    echo "hi"
+
+
+
+
+proc sayHi(name: string) =
+  echo "Hello ", name
+
+sayHi("World")
+sayHi("me!!")
+sayHi "World without paranthesis"
+"World ".sayHi
+
+
diff --git a/arrays.nim b/arrays.nim
new file mode 100644
index 0000000..a6c8d80
--- /dev/null
+++ b/arrays.nim
@@ -0,0 +1,328 @@
+# Copyright 2019.
+from strformat import fmt
+from strutils import repeat,join
+from algorithm import reversed
+import terminal
+
+let
+  i_arr1: array[0 .. 5, int] = [1,2,3,4,5,6]
+  i_arr2: array[6, int] = [7,8,9,10,11,12]
+
+echo i_arr1
+echo i_arr2
+
+# Normal arrays
+
+let
+  i_arr: array[6 .. 11, int] = [1,2,3,4,5,6]
+echo "min_index = ", low(i_arr),
+     ", max_index = ", high(i_arr),
+     ", i_arr = ", i_arr,
+     ", length= ", len(i_arr)
+
+# Typed arrays
+type
+  IntArray = array[6 .. 11, int]
+let
+  i_arr3: IntArray=[1,2,3,4,5,6]
+
+echo "min_index =", low(i_arr3),
+     ", max_index =", high(i_arr3),
+     ", i_arr3 =",i_arr3,
+     ", length =", len(i_arr3)
+
+# inferred array types
+let
+  arr1 = [1.0, 2,3,4]
+  arr2 = ['a','c','d']
+  arr3 = ["a", "bc", "def", "ghi", "klmno"]
+echo fmt"arr1 is of type {$type(arr1)} with value {arr1}"
+echo fmt"arr2 is of type {$type(arr2)} with value {arr2}"
+echo fmt"arr3 is of type {$type(arr3)} with value {arr3}"
+
+let
+  i_arry: array[6 .. 11, int] = [1, 2, 3, 4, 5, 6]
+echo "min_index = ",low(i_arry),"max_index = ",high(i_arry)
+
+
+# arrays with enum as length
+echo "“enum-length arrays” can serve as “dictionaries” to provide a one-to-one translation from each enum value to something else."
+echo "https://scripter.co/notes/nim#enum-length-arrays"
+type
+  Foo = enum
+    oneHundred
+    twoHundred
+    threeHundred
+proc dict(f:Foo) =
+  const
+    fooInt: array[Foo,int] = [100,200,300]
+    fooString: array[Foo,string] =  ["one hundered", "two hundred","three hundred"]
+  echo fooInt[f], " ", fooString[f]
+
+
+dict(twoHundred)
+
+#[
+  https://scripter.co/notes/nim#enum-length-arrays
+type
+  Foo2 = enum
+    oneHundred2
+    twoHundred2
+    threeHundred2
+
+proc dict(f:Foo2) =
+  const
+      fooInt2: array[Foo2,int] = [100,200]
+  echo fooInt2[f]
+]#
+styledEcho styleBright, fgRed,"“enum-length arrays” can serve as “dictionaries ",
+                              "to provide a one-to-one translation from each ",
+                              "enum value to something else."
+
+echo """
+type
+  PartsOfSpeech = enum
+    speechPronoun, speechVerb, speechArticle,
+    speechAdjection, speechNoun, speechAdverb
+let partOfSpeechExamples: array[PartsOfSpeech, string] = [
+  "he","reads","the","green","book","slowly"
+]
+echo partOfSpeechExamples
+"""
+
+type
+  PartsOfSpeech = enum
+    speechPronoun, speechVerb, speechArticle,
+    speechAdjection, speechNoun, speechAdverb
+let partOfSpeechExamples: array[PartsOfSpeech, string] = [
+  "he","reads","the","green","book","slowly"
+]
+echo partOfSpeechExamples
+
+echo ""
+echo "#Sequences -- @[1,2,3,4]"
+echo '-'.repeat(40)
+
+styledEcho styleBright,
+  fgRed,
+  "* Sequences are similar to arrays but of",
+  "dynamic length which may change during",
+  "runtime (like strings).\n",
+
+  "* In the sequence constructor @[1, 2, 3],",
+  "  the [] portion is actually the array constructor,",
+  "  and @ is the array to sequence operator.\n",
+
+  "* the sequence type does not need to be",
+  "specified if it is directly assigned a value"
+
+echo """
+let
+  i_seq1:seq[int] = @[1,2,3,4,5,6]
+  i_seq2 = @[7,8,9]
+
+echo fmt"i_seq1 is of type {$type(i_seq1)} with value {i_seq1}"
+echo fmt"i_seq2 is of type {$type(i_seq2)} with value {i_seq2}"
+"""
+
+let
+  i_seq1:seq[int] = @[1,2,3,4,5,6]
+  i_seq2 = @[7,8,9]
+
+echo fmt"i_seq1 is of type {$type(i_seq1)} with value {i_seq1}"
+echo fmt"i_seq2 is of type {$type(i_seq2)} with value {i_seq2}"
+
+echo ""
+echo "Sequence - features:"
+echo '-'.repeat(40)
+
+styledEcho styleBright,
+  fgRed,
+  " * append elements to a sequence with the add() proc or the & operator.\n",
+  " * pop() can be used to remove (and get) the last element of a sequence.\n",
+  " * high() returns the upper bound of a sequence.\n",
+  " * low() also works for a sequence, but it will always return 0.\n",
+  " * len() returns the sequence length.\n"
+
+var
+  i_secv:seq[int] = @[1,2,3,4,5,6,70]
+echo fmt"i_secv is of type {$type(i_secv)} with value {i_secv}"
+echo fmt"i_secv = {i_secv}, length is: {i_secv.len}, last element is: {i_secv[i_secv.high]}"
+styledEcho styleBright,
+  fgYellow,
+  "Adding 100 to the sequence! \n",
+  "i_secv.add(100)"
+i_secv.add(100)
+echo fmt"i_secv = {i_secv}, length is: {i_secv.len}, last element is: {i_secv[i_secv.high]}"
+styledEcho styleBright,
+  fgYellow,
+  "Adding 200 to the sequnece using '&'! \n",
+  "i_secv = i_secv & 200"
+i_secv = i_secv & 200
+echo fmt"i_secv = {i_secv}, length is: {i_secv.len}, last element is: {i_secv[i_secv.high]}"
+styledEcho styleBright,
+  fgYellow,
+  "Popping the last sequence element using pop() ... \n",
+  "let poppedElement = i_secv.pop"
+let poppedElement = i_secv.pop
+echo fmt" Popped element = {poppedElement}"
+echo fmt" i_secv = {i_secv}, length is: {i_secv.len}, last element is: {i_secv[i_secv.high]}"
+
+echo ""
+echo "Sequence - reversing:"
+echo '-'.repeat(40)
+
+
+styledEcho styleBright,
+  fgRed,
+  " * Reversed proc from the stdlib algorithm. \n",
+  " * It takes in arrays, sequences and strings, but always returns sequences.\n"
+echo """
+
+echo reversed([1,2,3,4,5])
+echo reversed(@[1,2,3,4,5])
+echo reversed("abcdef")
+"""
+echo reversed([1,2,3,4,5])
+echo reversed(@[1,2,3,4,5])
+echo reversed("abcdef")
+
+styledEcho styleBright,
+  fgRed,
+  " * reversed on a string returs individual chars reversed \n",
+  " * If you want a reversed string, just join those chars again.\n"
+echo """
+echo reversed("abcedf").join("")
+"""
+echo reversed("abcedf").join("")
+
+echo ""
+echo "Open arrays - "
+echo '-'.repeat(40)
+
+styledEcho styleBright,
+  fgRed,
+  " * Open array types are like dynamic arrays, and need to be\n",
+  "specified with only the type of the elements that the array is going to contain.\n",
+  " * This array type can be used only for parameters in procedures.\n",
+  " * Built-in proc high() returns the upper bound of an open array too.\n",
+  " * low() also works for an open array, but it will always return 0.\n",
+  " * len() returns the open array length. \n"
+
+echo """
+proc testOpenArray(x: openArray[int]) =
+  echo fmt" x = {x} (type: {type(x)}, length = {x.len}, max_index = {x.high})"
+
+let
+  someSeq = @[1,2,3]
+  someArr = [1,2,3,4,5,6]
+
+echo "Passing a sequence ... "
+testOpenArray(someSeq)
+echo "Passing an array ... "
+testOpenArray(someArr)
+"""
+
+proc testOpenArray(x: openArray[int]) =
+  echo fmt" x = {x} (type: {type(x)}, length = {x.len}, max_index = {x.high})"
+
+let
+  someSeq = @[1,2,3]
+  someArr = [1,2,3,4,5,6]
+
+echo "Passing a sequence ... "
+testOpenArray(someSeq)
+echo "Passing an array ... "
+testOpenArray(someArr)
+
+styledEcho styleBright,
+  fgRed,
+    " * you can have a proc parameter of type openArray[int], and have it\n",
+    " accept all of these types – array[5, int], array[1000, int], seq[int].. \n",
+    " just that the array|seq|openArray elements need to be of the exact same\n",
+    " type.. int in this case."
+
+
+type
+  MyArr = array[3, int]
+let
+  a3: MyArr = [10,20,30]
+  a4  = [10,20,30,40]
+echo '-'.repeat(40)
+echo """
+
+type
+  MyArr = array[3, int]
+let
+  a3: MyArr = [10,20,30]
+  a4  = [10,20,30,40]
+"""
+echo '-'.repeat(40)
+echo """
+# Compiler does not allow passing arratys with any other length
+proc countMyArr(a: MyArr): int =
+  for i in 0 .. a.high:
+    result += a[i]
+echo "countMyArray (a3) = ", countMyArr(a3)
+# countMyArray(a4) # will fail
+"""
+# Compiler does not allow passing arratys with any other length
+proc countMyArr(a: MyArr): int =
+  for i in 0 .. a.high:
+    result += a[i]
+echo "countMyArray (a3) = ", countMyArr(a3)
+# countMyArray(a4) # will fail
+echo '-'.repeat(40)
+echo """
+# Compiler does not allow passing arrays with any other length
+proc countExplicitArrayType(a: array[3,int]): int =
+  for i in 0 .. a.high:
+    result += a[i]
+
+echo "countExplicitArrayType (a3) = ", countExplicitArrayType(a3)
+# countExplicitArrayType(a4) # will fail
+"""
+# Compiler does not allow passing arrays with any other length
+proc countExplicitArrayType(a: array[3,int]): int =
+  for i in 0 .. a.high:
+    result += a[i]
+
+echo "countExplicitArrayType (a3) = ", countExplicitArrayType(a3)
+# countExplicitArrayType(a4) # will fail
+echo '-'.repeat(40)
+echo """
+# Compiler allows passing arrays with different lengths
+proc countOpenArray(a: openArray[int]): int =
+  for i in 0 .. a.high:
+    result += a[i]
+echo "countOpenArray(a3) = ", countOpenArray(a3)
+echo "countOpenArray(a4) = ", countOpenArray(a4)
+"""
+# Compiler allows passing arrays with different lengths
+proc countOpenArray(a: openArray[int]): int =
+  for i in 0 .. a.high:
+    result += a[i]
+echo "countOpenArray(a3) = ", countOpenArray(a3)
+echo "countOpenArray(a4) = ", countOpenArray(a4)
+#[
+
+proc foo(i_oa: openArray[int]) =
+    var i_seq: seq[int] = i_oa
+    i_seq.add(100)
+    echo "input open array: ", i_oa
+    echo "that open array modified to a sequence: ", i_seq
+#foo(@[10,20,30,40])
+]#
+#[ proc foo2(i_oa: openArray[int]) =
+  var i_seq2: seq[int]
+  for i in i_oa: # copying the input openarray to seq element by element
+    i_seq2.add(i)
+  i_seq2.add(100)
+  echo "input open array2: ", i_oa
+  echo "that open array2 modified to a sequence: ", i_seq
+foo(@[10, 20, 30, 40]) ]#
+
+
+proc foo3(x: openArray[int]) =
+  echo fmt"{x}"
+foo3([1, 2, 3])
diff --git a/fsm.nim b/fsm.nim
new file mode 100644
index 0000000..afc14f4
--- /dev/null
+++ b/fsm.nim
@@ -0,0 +1,18 @@
+import
+  tables,
+  strutils,
+  options
+
+type
+  Callback        = proc(): void
+  StateEvent[S,E] = tuple[state: S, event: E]
+  Transition[S]   = tuple[nexState: S, action: Option[Callback]]
+
+  Machine[S,E]    = ref object of RootObj
+    intialState:      S
+    currentState:     Option[S]
+    transitions:      TableRef[StateEvent[S,E], Transition[S]]
+    transitionsAny:   TableRef[S, Transition[S]]
+    defaultTransition:Option[Transition[S]]
+
+  TransitionNotFoundException = object of Exception
diff --git a/getalphabet.nim b/getalphabet.nim
new file mode 100644
index 0000000..6eff5e2
--- /dev/null
+++ b/getalphabet.nim
@@ -0,0 +1,49 @@
+# Copyright 2019.'
+import terminal
+
+proc getAlphabet(): string =
+  var accm = ""
+  for letter in 'a' .. 'z':
+    accm.add(letter)
+  return accm
+stdout.styledWrite(fgRed,
+"""
+    proc getAlphabet(): string =
+      var accm = ""
+      for letter in 'a' .. 'z':
+        accm.add(letter)
+      return accm
+
+    echo getAlphabet()
+""")
+echo getAlphabet()
+
+stdout.styledWrite(fgGreen,
+            """
+      The result variable is a special variable that serves
+      as an implicit return variable, which exists because the
+      control flow semantics of the return statement are rarely needed.
+      The result variable is initialized in the standard way,
+      as if it was declared with:""")
+proc getalphabetx(): string =
+  result = ""
+  for letter in 'a' .. 'z':
+    result.add(letter)
+
+stdout.styledWrite(fgRed,
+            """
+  proc getalphabetx(): string =
+    result = ""
+    for letter in 'a' .. 'z':
+      result.add(letter)
+
+  echo getAlphabetx()
+    """)
+echo getAlphabetx()
+
+
+proc unexpected(): int =
+  var result = 4
+  result += 5
+
+echo unexpected()
diff --git a/hslice.nim b/hslice.nim
new file mode 100644
index 0000000..c8a2116
--- /dev/null
+++ b/hslice.nim
@@ -0,0 +1,37 @@
+# Copyright 2019.
+import strformat
+var s1: HSlice[int,char]
+s1.a = 4
+s1.b = 'f'
+echo fmt"s1=`{s1}` is of type {$type(s1)}"
+
+let hs1 = 1 .. 3
+echo fmt"hs1=`{hs1}` is of type {$type(hs1)}"
+for n in hs1:
+  echo n
+let
+  hs2 = 'k' .. 'm'
+echo fmt"hs2=`{hs2}` is of type {$type(hs2)}"
+for c in hs2:
+  echo c
+
+let str = "abcdefghijk"
+echo str[2 .. 4]
+
+let
+  hs3 = 1 .. 'z'
+  hs4 = 0.99 .. "blah"
+echo fmt"hs3=`{hs3}` is of type {$type(hs3)}"
+echo fmt"hs4=`{hs4}` is of type {$type(hs4)}"
+
+let
+  hs5 = 777 .. 'd' .. "foo"
+  hs6 = (777 .. 'd') .. "foo"
+  hs7 = 5 .. 6 .. 'x' .. 'y'
+  hs8 = ((5 .. 6) .. 'x') .. 'y'
+
+echo fmt"hs5=`{hs5}` is of type {$type(hs5)}"
+echo fmt"hs6=`{hs6}` is of type {$type(hs6)}"
+echo fmt"hs7=`{hs7}` is of type {$type(hs7)}"
+echo fmt"hs8=`{hs8}` is of type {$type(hs8)}"
+
diff --git a/macros2.nim b/macros2.nim
new file mode 100644
index 0000000..018051c
--- /dev/null
+++ b/macros2.nim
@@ -0,0 +1,62 @@
+import macros
+
+type
+  ShapeKind {.pure.} = enum
+    Triangle, Rectangle
+
+  Shape = object
+    case kind: ShapeKind
+    of Triangle:
+      aT: int
+      bT: int
+    of Rectangle:
+      aR: int
+      bR: int
+
+proc calcArea(s: Shape) =
+  discard
+
+proc createNext(c: Nimnode): NimNode =
+  let typ = c[0]
+  let name = c[1]
+  let a = c[2][0][0]
+  let aVal = c[2][0][1]
+  let b = c[2][1][0]
+  let bVal = c[2][1][1]
+
+  case $typ
+  of "Triangle":
+    a.ident = toNimIdent($a & "T")
+    b.ident = toNimIdent($b & "T")
+  of "Rectangle":
+    a.ident = toNimIdent($a & "R")
+    b.ident = toNimIdent($b & "R")
+  result = quote do:
+    let `name` = Shape(kind: `typ`, `a`: `aVal`, `b`: `bVal`)
+    `name`.calcArea()
+
+macro shape(input: untyped): untyped =
+  # should produce
+    #   let aaa = Shape(kind: Triangle, a:17 , b:23)
+    #   aaa.calcArea()
+    #   let bbb = Shape(kind: Rectangle, a:5, b:8)
+    #   bbb.calcArea()
+  result = newStmtList()
+  echo input.treeRepr
+  for i in 0 ..< input.len:
+    let c = input[i]
+    case c.kind
+    of nnkCommand:
+      result.add createNext(c)
+    else:
+      echo "Needs to be a command"
+
+  echo result.repr
+
+shape:
+  Triangle aaa:
+    a = 17
+    b = 23
+  Rectangle bbb:
+    a = 5
+    b = 8
diff --git a/nimboxtest.nim b/nimboxtest.nim
new file mode 100644
index 0000000..9850969
--- /dev/null
+++ b/nimboxtest.nim
@@ -0,0 +1,15 @@
+import nimbox
+import os
+
+when isMainModule:
+  var nb = newNimbox()
+
+
+  nb.print(0, 0, "Hello, world!", clrRed, clrGreen, styUnderline)
+  nb.present()
+  sleep(1000)
+
+  nb.print(0, 0, "Hello, world!", clrRed, clrGreen, styUnderline and styBold)
+  nb.present()
+  sleep(1000)
+
diff --git a/stackpollute.nim b/stackpollute.nim
new file mode 100644
index 0000000..219776f
--- /dev/null
+++ b/stackpollute.nim
@@ -0,0 +1,10 @@
+import random, math
+
+proc pollutestack()=
+  var
+    c:char = (rand(high(char).int)).char
+    i32: int32 = (rand(high(int32).int)).int32
+    i64: int64 = (rand(high(int64).int)).int64
+    f32: float32 = (rand(high(int64).int)).float32
+    f64: float64 = (rand(high(int64).int)).float64
+    b: bool = rand(1).bool
diff --git a/stuff.nim b/stuff.nim
new file mode 100644
index 0000000..019c35f
--- /dev/null
+++ b/stuff.nim
@@ -0,0 +1,119 @@
+import terminal
+
+assert NimVersion is string
+echo "NimVersion is: " & NimVersion
+assert NimMajor is int
+echo $NimMajor & " is the NimMajor"
+assert NimMinor is int
+echo $NimMinor & " is the NimMinor"
+assert NimPatch is int
+echo $NimPatch & " is the NimPatch"
+
+echo ("Hello world!")
+echo "Hello world!"
+
+echo $100 & "abc" & $2.4
+
+styledEcho "styledEcho unstyled text", styleBright, fgGreen,
+  " styleBright, fgGreen [PASS]",
+  resetStyle, fgGreen, " resetStyle, fgGreen, Yay!"
+
+styledEcho "styledEcho unstyled text", styleBright, fgRed,
+  " styleBright, fgRed,  [FAIL]",
+  resetStyle, fgRed, " resetStyle, fgRed,   Nay!"
+
+stdout.styledWrite(fgRed,
+    "stdout.styledWrite(fgRed,\"Red Text\" - no new line ")
+stdout.styledWrite(fgGreen, "same as above but Green Text ")
+echo ""
+echo "ForeGroundcolor - globally - setForeGroundColor(fgGreen)"
+setForeGroundColor(fgGreen)
+echo "Green Text"
+echo "Some more green text"
+setBackgroundColor(bgRed)
+
+echo "after setBackgroundColor(bgRed)"
+
+resetAttributes()
+
+echo "after resetAttributes() - Line 1"
+echo "Line 2"
+echo "Line 3"
+
+stdout.styledWrite(fgGreen, bgRed,
+    "stdout.styledWrite(fgGreen, bgRed, with \"\\n\"\n")
+
+stderr.writeLine "Error!"
+echo"To send messages to stderr that don’t end in newlines, use stderr.write instead."
+stderr.write "Error1"
+stderr.write "Error2"
+echo "\n"
+
+proc isTriangle(s: openArray[int]): bool =
+  return (s.len == 3) and
+    (s[0] <= s[1] + s[2]) and
+    (s[1] <= s[2] + s[0]) and
+    (s[2] <= s[0] + s[1]) and
+    (s[0] > 0) and
+    (s[1] > 0) and
+    (s[2] > 0)
+
+
+
+
+echo """
+Asta merge:
+proc isTriangle(s: openArray[int]): bool =
+  return (s.len == 3) and
+    (s[0] <= s[1] + s[2]) and
+    (s[1] <= s[2] + s[0]) and
+    (s[2] <= s[0] + s[1]) and
+    (s[0] > 0) and
+    (s[1] > 0) and
+    (s[2] > 0)
+
+    echo isTriangle([3, 3, 3])
+
+Asta nu merge:
+  stuff.nim(54, 5) Error: invalid indentation
+proc isTriangle(s: openArray[int]): bool =
+  return (s.len == 3)
+    and (s[0] <= s[1] + s[2])
+    and (s[1] <= s[2] + s[0])
+    and (s[2] <= s[0] + s[1])
+    and (s[0] > 0)
+    and (s[1] > 0)
+    and (s[2] > 0)
+
+    echo isTriangle([3, 3, 3])
+"""
+
+echo isTriangle([3, 3, 3])
+
+# Template
+
+template foo(body): untyped =
+  body
+
+foo(): #special colon
+  echo "hello"
+  echo "world"
+echo " assign the correct return type for the foo template:"
+echo """
+template foo2(): array =
+  [1, 1]
+echo foo2
+"""
+template foo2(): array =
+  [1, 1]
+echo foo2
+
+echo "Or set it to untyped so that the template replacement is done before any semantic checking or type resolution."
+echo """
+template foo3(): untyped =
+  [1, 2]
+echo foo3
+"""
+template foo3(): untyped =
+  [1, 2]
+echo foo3
diff --git a/trmacros.nim b/trmacros.nim
new file mode 100644
index 0000000..081cb08
--- /dev/null
+++ b/trmacros.nim
@@ -0,0 +1,26 @@
+# Copyright 2019.
+import strformat
+
+template optMul{`*`(a, 2)}(a: int): int =
+  debugEcho("-> Term Rewriting activated! ")
+  a + a
+
+echo fmt"First arg = 3 ({$3.type})"
+echo "Calculating 3 * 2:"
+echo 3 * 2
+
+let x = 3
+echo ""
+echo fmt"First arg = x ({$x.type})"
+echo "Calcualting x * 2:"
+echo x * 2
+
+
+echo ""
+echo fmt"First arg = 2 ({$2.type})"
+echo "Calcualting 2 * x:"
+echo 2 * x
+
+echo "'c' is char ? ", 'c' is char
+echo "'c' is string ? ", 'c' is string
+echo "'c' is int ? ", 'c' is int
diff --git a/variables.nim b/variables.nim
new file mode 100644
index 0000000..5e30378
--- /dev/null
+++ b/variables.nim
@@ -0,0 +1,27 @@
+# Copyright 2019.
+echo "Mutable (var)"
+
+
+var
+    a = "foo"
+    b = 0
+    c: int
+
+echo a
+echo b
+echo c
+
+a.add("baz")
+b += 1
+c += 3
+
+
+echo a
+echo b
+echo c
+let
+    d = "foo"
+    e = 5
+    f:float = 1
+
+echo d,e,f