Skip to content

Instantly share code, notes, and snippets.

@dgellow
Last active August 29, 2015 14:24
Show Gist options
  • Save dgellow/7bb55a392215a45997b6 to your computer and use it in GitHub Desktop.
Save dgellow/7bb55a392215a45997b6 to your computer and use it in GitHub Desktop.
Some fun with Nim. Based on http://learnxinyminutes.com/docs/nim/
import strutils as str
import math except sin
# Helpers
proc newline(text: string): string =
text & "\r\n"
proc colorize(text: string, color: int, isBright: bool): string =
let
boldVal: int = if isBright: 1
else: 0
"\e[$1;$2m$3\e[0m" % [boldVal.intToStr, color.intToStr, text]
proc writecolor(text: string, color: int, bright = false): void =
write(stdout, colorize(text, color, bright))
proc echocolor(text: string, color: int, bright = false): void =
write(stdout, newline(colorize(text, color, bright)))
proc echoTitle(title: string): void =
let
decoration = "—".repeat(len(title))
color = 30
isBright = true
discard map(@[decoration, title, decoration],
proc (x: string): string =
echocolor x, color, isBright)
# Introduction
var
letter: char = 'n'
lang = "N" & "im"
nLength: int = len lang
boat: float
truth: bool = false
let
legs = 400
arms = 2_000
aboutPi = 3.141592653589
const
debug = true
compileBadCode = false
when compileBadCode:
legs = legs + 1
const input = readline(stdin)
discard 1 > 2
discard map([1, 2, 3], proc (x: int): string = "Num:" & intToStr(x))
#
# Data Structures
#
# Tuples
echoTitle "Tuples"
var
child: tuple[name: string, age: int]
today: tuple[sun: string, temp: float]
child = (name: "Sam", age: 23)
today.sun = "Overcast"
today.temp = 34
echo child
echo today
# Sequences
var
drinks: seq[string]
drinks = @["Water", "Juice", "Chocolate"]
#
# Defining types
#
type
Name = string # type alias
Age = int
Person = tuple[name: Name, age: Age] # define data structures
AnotherSyntax = tuple
fieldOne: string
secondField: int
var
john: Person = (name: "John B.", age: 17)
newage: int = 18
john.age = newage # it works since Age and int are synonyms
type
# 'distinct' makes a new type incompatible with its
# base type.
Cash = distinct int
Desc = distinct string
var
money: Cash = 100.Cash
description: Desc = "Interesting".Desc
when compileBadCode:
john.age = money # Error! age is of type int and money is Cash
john.name = description # Error too
#
# More types and data structures
#
# Enum
echoTitle "Enum"
type
Color = enum cRed, cBlue, cGreen
Direction = enum
dNorth
dWest
dEast
dSouth
var
# 'orientation' is of type Direction, value is 'dNorth'
orientation = dNorth
# 'pixel' is of type Color, value is 'cGreen'
pixel = cGreen
echo "Is North bigger than East?"
echo dNorth > dEast
echo "Is North smaller than East?"
echo dNorth < dEast
type
# Only an int from 1 to 20 is a valid value
DieFaces = range[1..20]
var
my_roll: DieFaces = 13
when compileBadCode:
my_roll = 23
# Arrays
echoTitle "Arrays"
type
# Arrays are fixed length and indexed by an ordinal type
RollCounter = array[DieFaces, int] # array length = length of DieFaces
DirectionNames = array[Direction, string]
Truths = array[42..44, bool]
var
counter: RollCounter
directions: DirectionNames
possible: Truths
possible = [false, false, false]
possible[42] = true
when compileBadCode:
possible[41] = true # Error: index out of bounds
directions[dNorth] = "The great white north"
directions[dWest] = "Don't go there! I saw a giant spider last night!"
my_roll = 13
echo "Counter dice roll: " & counter[my_roll].intToStr
counter[my_roll] += 1
echo "Counter dice roll: " & counter[my_roll].intToStr
counter[my_roll] += 1
echo "Counter dice roll: " & counter[my_roll].intToStr
var anotherArray = ["Default index", "starts at", "0"]
#
# IO and Control Flow
#
# 'case', 'readLine()'
echoTitle "'case', 'readLine()'"
echo "Read any good books lately? [y/n]"
case readLine(stdin).toLower
of "n", "no":
echo "You should go to your local library."
of "y", "yes":
echo "Carry on, then!"
else:
echo "Uggh? Not sure to understand, but I assume that's great?"
# 'while', 'if', 'continue', 'break'
echoTitle "'while', 'if', 'continue', 'break'"
echo "I'm thinking of a number between 0 and 50. Guess which one!"
randomize()
let
number_to_guess: int = toInt(random(49.0) + 1)
var
raw_guess: string
guess: int
while guess != number_to_guess:
raw_guess = readLine(stdin)
if raw_guess == "": continue
guess = parseFloat(raw_guess).toInt
echo "toGuess: " & number_to_guess.intToStr
echo "guess: " & guess.intToStr
if guess > number_to_guess:
echo("Nope. Too high. You lose.")
break;
elif guess < number_to_guess:
echo("Your guess is too low.")
else:
echo("Good game, you found it.")
#
# Iteration
#
echoTitle "Iteration"
for i, elem in ["Yes", "No", "Maybe so"]:
echo(elem, " is at index:", i)
for pers, power in items(@[(person: "You", power: 100),
(person: "Me", power: 9000)]):
echo "Person: " & pers
echo "Power: " & power.intToStr
# Multiline raw string
echoTitle "Multiline"
let myString = """
an <example>
`string` to
play with
"""
for line in splitLines(myString):
echo line
for i, c in myString:
if i mod 2 == 0: continue
elif c == 'X': break
else: echo c
#
# Procedures
#
echoTitle("Procedures")
type
Answer = enum aYes, aNo
proc ask(question: string): Answer =
echo question, " [y/n]"
while true:
case readLine(stdin).toLower
of "y", "yes":
return Answer.aYes
of "n", "no":
return Answer.aNo
else: echo "Please be clear: yes or no"
proc addSugar(amount: int = 2) =
assert(amount > 0 or amount < 9000, "Crazy Sugar")
for a in 1..amount:
echo a, " sugar..."
case ask("Would you like sugar in your tea?")
of aYes:
addSugar(3)
of aNo:
echo "Oh ... do take a little!"
addSugar()
#
# FFI
#
echoTitle "FFI"
proc sin(angle: float): float {.importc: "sin", nodecl.}
echo "Some sinus values:"
for angle in @[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]:
echo "angle: " & $angle & " rad | sin(angle): " & $sin(angle)
#
# Higher Order functions
#
echoTitle "Higher order functions"
proc first(s: seq, sortfn: proc, mapfn: proc): auto =
s.sorted(sortfn).map(mapfn)
proc second(n: int):int =
n * 1000
echo first(@[5, 6, 3, 2, 0], system.cmp[int], second)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment