Warning, /frameworks/syntax-highlighting/autotests/input/test.nim is written in an unsupported language. File is not indexed.
0001 # Nim Sample file 0002 # Obtained form: https://nim-by-example.github.io/ 0003 0004 # Comment ALERT NOTE FIXME 0005 #[ Multi-line 0006 comment ]# 0007 0008 ## Documentation comment 0009 ##[ Multi-line 0010 documentation comment ]## 0011 0012 import strformat 0013 0014 type 0015 Person = object 0016 name: string 0017 age: Natural # Ensures the age is positive 0018 0019 let people = [ 0020 Person(name: "John", age: 45), 0021 Person(name: "Kate", age: 30) 0022 ] 0023 0024 for person in people: 0025 # Type-safe string interpolation, 0026 # evaluated at compile time. 0027 echo(fmt"{person.name} is {person.age} years old") 0028 0029 # Thanks to Nim's 'iterator' and 'yield' constructs, 0030 # iterators are as easy to write as ordinary 0031 # functions. They are compiled to inline loops. 0032 iterator oddNumbers[Idx, T](a: array[Idx, T]): T = 0033 for x in a: 0034 if x mod 2 == 1: 0035 yield x 0036 0037 for odd in oddNumbers([3, 6, 9, 12, 15, 18]): 0038 echo odd 0039 0040 # Use Nim's macro system to transform a dense 0041 # data-centric description of x86 instructions 0042 # into lookup tables that are used by 0043 # assemblers and JITs. 0044 import macros, strutils 0045 0046 macro toLookupTable(data: static[string]): untyped = 0047 result = newTree(nnkBracket) 0048 for w in data.split(';'): 0049 result.add newLit(w) 0050 0051 const 0052 data = "mov;btc;cli;xor" 0053 opcodes = toLookupTable(data) 0054 0055 for o in opcodes: 0056 echo o 0057 0058 # Variables 0059 proc getAlphabet(): string = 0060 var accm = "" 0061 for letter in 'a'..'z': # see iterators 0062 accm.add(letter) 0063 return accm 0064 0065 # Computed at compilation time 0066 const alphabet = getAlphabet() 0067 0068 # Mutable variables 0069 var 0070 a = "foo" 0071 b = 0 0072 # Works fine, initialized to 0 0073 c: int 0074 0075 # Immutable variables 0076 let 0077 d = "foo" 0078 e = 5 0079 # Compile-time error, must be initialized at creation 0080 f: float 0081 0082 # Works fine, `a` is mutable 0083 a.add("bar") 0084 b += 1 0085 c = 3 0086 0087 # Compile-time error, const cannot be modified at run-time 0088 alphabet = "abc" 0089 0090 # Compile-time error, `d` and `e` are immutable 0091 d.add("bar") 0092 e += 1 0093 0094 # Const 0095 STRING_LITERAL(TMP129, "abcdefghijklmnopqrstuvwxyz", 26); 0096 0097 # Loops 0098 import strutils, random 0099 0100 randomize() 0101 let answer = random(10) + 1 0102 while true: 0103 echo "I have a number from 1 to 10, what is it? " 0104 let guess = parseInt(stdin.readLine) 0105 0106 if guess < answer: 0107 echo "Too low, try again" 0108 elif guess > answer: 0109 echo "Too high, try again" 0110 else: 0111 echo "Correct!" 0112 break 0113 0114 block busyloops: 0115 while true: 0116 while true: 0117 break busyloops 0118 0119 # Case Statements 0120 case "charlie": 0121 of "alfa": 0122 echo "A" 0123 of "bravo": 0124 echo "B" 0125 of "charlie": 0126 echo "C" 0127 else: 0128 echo "Unrecognized letter" 0129 0130 case 'h': 0131 of 'a', 'e', 'i', 'o', 'u': 0132 echo "Vowel" 0133 of '\127'..'\255': 0134 echo "Unknown" 0135 else: 0136 echo "Consonant" 0137 0138 proc positiveOrNegative(num: int): string = 0139 result = case num: 0140 of low(int).. -1: 0141 "negative" 0142 of 0: 0143 "zero" 0144 of 1..high(int): 0145 "positive" 0146 else: 0147 "impossible" 0148 0149 echo positiveOrNegative(-1) 0150 0151 # items and pairs 0152 type 0153 CustomRange = object 0154 low: int 0155 high: int 0156 0157 iterator items(range: CustomRange): int = 0158 var i = range.low 0159 while i <= range.high: 0160 yield i 0161 inc i 0162 0163 iterator pairs(range: CustomRange): tuple[a: int, b: char] = 0164 for i in range: # uses CustomRange.items 0165 yield (i, char(i + ord('a'))) 0166 0167 for i, c in CustomRange(low: 1, high: 3): 0168 echo c 0169 0170 # Operators 0171 iterator `...`*[T](a: T, b: T): T = 0172 var res: T = T(a) 0173 while res <= b: 0174 yield res 0175 inc res 0176 0177 for i in 0...5: 0178 echo i 0179 0180 # Inline Iterators 0181 iterator countTo(n: int): int = 0182 var i = 0 0183 while i <= n: 0184 yield i 0185 inc i 0186 0187 for i in countTo(5): 0188 echo i 0189 0190 # Closure Iterators 0191 proc countTo(n: int): iterator(): int = 0192 return iterator(): int = 0193 var i = 0 0194 while i <= n: 0195 yield i 0196 inc i 0197 0198 let countTo20 = countTo(20) 0199 0200 echo countTo20() 0201 0202 var output = "" 0203 # Raw iterator usage: 0204 while true: 0205 # 1. grab an element 0206 let next = countTo20() 0207 # 2. Is the element bogus? It's the end of the loop, discard it 0208 if finished(countTo20): 0209 break 0210 # 3. Loop body goes here: 0211 output.add($next & " ") 0212 0213 echo output 0214 0215 output = "" 0216 let countTo9 = countTo(9) 0217 for i in countTo9(): 0218 output.add($i) 0219 echo output 0220 0221 # Procs 0222 proc fibonacci(n: int): int = 0223 if n < 2: 0224 result = n 0225 else: 0226 result = fibonacci(n - 1) + (n - 2).fibonacci 0227 0228 # Operators 0229 proc `$`(a: array[2, array[2, int]]): string = 0230 result = "" 0231 for v in a: 0232 for vx in v: 0233 result.add($vx & ", ") 0234 result.add("\n") 0235 0236 echo([[1, 2], [3, 4]]) # See varargs for 0237 # how echo works 0238 0239 proc `^&*^@%`(a, b: string): string = 0240 ## A confusingly named useless operator 0241 result = a[0] & b[high(b)] 0242 0243 assert("foo" ^&*^@% "bar" == "fr") 0244 0245 # Generic Functions 0246 # Not really good idea for obvious reasons 0247 let zero = "" 0248 proc `+`(a, b: string): string = 0249 a & b 0250 0251 proc `*`[T](a: T, b: int): T = 0252 result = zero 0253 for i in 0..b-1: 0254 result = result + a # calls `+` from line 3 0255 0256 assert("a" * 10 == "aaaaaaaaaa") 0257 0258 # Blocks 0259 block outer: 0260 for i in 0..2000: 0261 for j in 0..2000: 0262 if i+j == 3145: 0263 echo i, ", ", j 0264 break outer 0265 0266 let b = 3 0267 block: 0268 let b = "3" # shadowing is probably a dumb idea 0269 0270 # Primitive types 0271 let 0272 a: int8 = 0x7F # Works 0273 b: uint8 = 0b1111_1111 # Works 0274 d = 0xFF # type is int 0275 c: uint8 = 256 # Compile time error 0276 let 0277 a: int = 2 0278 b: int = 4 0279 echo 4/2 0280 0281 # Types Aliases 0282 type 0283 MyInteger* = int 0284 0285 let a: int = 2 0286 discard a + MyInteger(4) 0287 0288 # Objects 0289 type 0290 Animal* = object 0291 name*, species*: string 0292 age: int 0293 0294 proc sleep*(a: var Animal) = 0295 a.age += 1 0296 0297 proc dead*(a: Animal): bool = 0298 result = a.age > 20 0299 0300 var carl: Animal 0301 carl = Animal(name : "Carl", 0302 species : "L. glama", 0303 age : 12) 0304 0305 let joe = Animal(name : "Joe", 0306 species : "H. sapiens", 0307 age : 23) 0308 0309 assert(not carl.dead) 0310 for i in 0..10: 0311 carl.sleep() 0312 assert carl.dead 0313 0314 # Enums 0315 type 0316 CompassDirections = enum 0317 cdNorth, cdEast, cdSouth, cdWest 0318 0319 Colors {.pure.} = enum 0320 Red = "FF0000", Green = (1, "00FF00"), Blue = "0000FF" 0321 0322 Signals = enum 0323 sigQuit = 3, sigAbort = 6, sigKill = 9 0324 0325 # Distinct Types 0326 type 0327 Dollars* = distinct float 0328 0329 var a = 20.Dollars 0330 a = 25 # Doesn't compile 0331 a = 25.Dollars # Works fine 0332 0333 # Strings 0334 echo "words words words ⚑" 0335 echo """ 0336 <html> 0337 <head> 0338 </head>\n\n 0339 0340 <body> 0341 </body> 0342 </html> """ 0343 0344 proc re(s: string): string = s 0345 0346 echo r"."".\s\" # Raw string 0347 echo re"\b[a-z]++\b" # Regular expression 0348 echo function"text" # Tagged string 0349 0350 # Arrays 0351 type 0352 ThreeStringAddress = array[3, string] 0353 let names: ThreeStringAddress = ["Jasmine", "Ktisztina", "Kristof"] 0354 let addresses: ThreeStringAddress = ["101 Betburweg", "66 Bellion Drive", "194 Laarderweg"] 0355 0356 type 0357 Matrix[W, H: static[int]] = 0358 array[1..W, array[1..H, int]] 0359 0360 let mat1: Matrix[2, 2] = [[1, 0], 0361 [0, 1]] 0362 let mat2: Matrix[2, 2] = [[0, 1], 0363 [1, 0]] 0364 0365 proc `+`[W, H](a, b: Matrix[W, H]): 0366 Matrix[W, H] = 0367 for i in 1..high(a): 0368 for j in 1..high(a[0]): 0369 result[i][j] = a[i][j] + b[i][j] 0370 0371 # Seqs 0372 var 0373 a = @[1, 2, 3] 0374 b = newSeq[int](3) 0375 0376 for i, v in a: 0377 b[i] = v*v 0378 0379 for i in 4..100: 0380 b.add(i * i) 0381 0382 b.delete(0) # takes O(n) time 0383 b = a[0] & b # Same as original b 0384 0385 # JSON 0386 import json 0387 0388 let element = "Hydrogen" 0389 let atomicNumber = 1 0390 0391 let jsonObject = %* {"element": element, "atomicNumber": atomicNumber} 0392 # This will print {"element":"Hydrogen", "atomicNumber": 1} 0393 echo $jsonObject 0394 0395 # We start with a string representation of a JSON object 0396 let jsonObject = """{"name": "Sky", "age": 32}""" 0397 let jsonArray = """[7, 8, 9]""" 0398 0399 let parsedObject = parseJson(jsonObject) 0400 let name = parsedObject["name"].getStr() 0401 # This will print Sky 0402 echo name 0403 0404 let parsedArray = parseJson(jsonArray) 0405 let eight = parsedArray[1].getInt() 0406 # This will print 8 0407 echo eight 0408 0409 # First we'll define our types 0410 type 0411 Element = object 0412 name: string 0413 atomicNumber: int 0414 0415 # Let's say this is the JSON we want to convert 0416 let jsonObject = parseJson("""{"name": "Carbon", "atomicNumber": 6}""") 0417 0418 let element = to(jsonObject, Element) 0419 # This will print Carbon 0420 echo element.name 0421 # This will print 6 0422 echo element.atomicNumber 0423 0424 # Object Oriented Programming 0425 type Animal = ref object of RootObj 0426 name: string 0427 age: int 0428 method vocalize(this: Animal): string {.base.} = "..." 0429 method ageHumanYrs(this: Animal): int {.base.} = this.age 0430 0431 type Dog = ref object of Animal 0432 method vocalize(this: Dog): string = "woof" 0433 method ageHumanYrs(this: Dog): int = this.age * 7 0434 0435 type Cat = ref object of Animal 0436 method vocalize(this: Cat): string = "meow" 0437 0438 var animals: seq[Animal] = @[] 0439 animals.add(Dog(name: "Sparky", age: 10)) 0440 animals.add(Cat(name: "Mitten", age: 10)) 0441 0442 for a in animals: 0443 echo a.vocalize() 0444 echo a.ageHumanYrs() 0445 0446 let slash = "\\"