summary refs log tree commit diff stats
path: root/tests/concepts/t18409.nim
blob: 0edba2d31e482278e9870f2fc607ccf14867c80b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
discard """
  action: "compile"
"""

# A vector space over a field F concept.
type VectorSpace*[F] = concept x, y, type V
  vector_add(x, y) is V
  scalar_mul(x, F) is V
  dimension(V) is Natural

# Real numbers (here floats) form a vector space.
func vector_add*(v: float, w: float): float =  v + w
func scalar_mul*(v: float, s: float): float =   v * s
func dimension*(x: typedesc[float]): Natural = 1

# 2-tuples of real numbers form a vector space.
func vector_add*(v, w: (float, float)): (float, float) =
  (vector_add(v[0], w[0]), vector_add(v[1], w[1]))

func scalar_mul*(v: (float, float), s: float): (float, float) =
  (scalar_mul(v[0], s), scalar_mul(v[1], s))

func dimension*(x: typedesc[(float, float)]): Natural = 2

# Check concept requirements.
assert float is VectorSpace
assert (float, float) is VectorSpace

# Commutivity axiom for vector spaces over the same field.
func axiom_commutivity*[F](u, v: VectorSpace[F]): bool =
  vector_add(u, v) == vector_add(v, u)

# This is okay.
assert axiom_commutivity(2.2, 3.3)

# This is not.
assert axiom_commutivity((2.2, 3.3), (4.4, 5.5))

                                 
             
                               
                                         
                           
                                         
                                                                 



                                               
                     
                                        
     
                                                 
# Simple tool to merge C projects into a single C file

import os, sets, pegs

type
  ProcessResult = enum prSkipIncludeDir, prAddIncludeDir

proc process(dir, infile: string, outfile: File,
             processed: var HashSet[string]): ProcessResult =
  if processed.containsOrIncl(infile): return prSkipIncludeDir
  let toProcess = dir / infile
  if not existsFile(toProcess):
    echo "Warning: could not process: ", toProcess
    return prAddIncludeDir
  echo "adding: ", toProcess
  for line in lines(toProcess):
    if line =~ peg"""s <- ig '#include' ig '"' {[^"]+} '"' ig
                     comment <- '/*' !'*/'* '*/' / '//' .*
                     ig <- (comment / \s+)* """:
      # follow the include file:
      if process(dir, matches[0], outfile, processed) == prAddIncludeDir:
        writeLine(outfile, line)
    else:
      writeLine(outfile, line)

proc main(dir, outfile: string) =
  var o: File
  if open(o, outfile, fmWrite):
    var processed = initHashSet[string]()
    processed.incl(outfile)
    for infile in walkFiles(dir / "*.c"):
      discard process(dir, extractFilename(infile), o, processed)
    close(o)
  else:
    quit("Cannot open for writing: " & outfile)

if paramCount() != 2:
  quit "Usage: cmerge directory outfile"
else:
  main(paramStr(1), addFileExt(paramStr(2), "c"))