Code coverage report for sc/lang/fn.js

Statements: 100% (64 / 64)      Branches: 100% (27 / 27)      Functions: 100% (11 / 11)      Lines: 100% (64 / 64)      Ignored: none     

All files » sc/lang/ » fn.js
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 1201     1 1   1 1   1 1655 1655   1655 1281     374 374 9     374 374   374 648 648 648     374 6678   6678 6678   6678 1     6678   6678 17     6678     374 374   374     1 6678     1 6678 8621 8608         1 650   650   476   3   5   6   1     159 159   1   20     138 35     103     1 648 1 3     647     1 1 2 2 1         1    
(function(sc) {
  "use strict";
 
  require("./lang");
  require("./dollar");
 
  var slice = [].slice;
  var $ = sc.lang.$;
 
  var fn = function(func, def) {
    var argItems, argNames, argVals;
    var remain, wrapper;
 
    if (!def) {
      return func;
    }
 
    argItems = def.split(/\s*;\s*/);
    if (argItems[argItems.length - 1].charAt(0) === "*") {
      remain = !!argItems.pop();
    }
 
    argNames = new Array(argItems.length);
    argVals  = new Array(argItems.length);
 
    argItems.forEach(function(items, i) {
      items = items.split("=");
      argNames[i] = items[0].trim();
      argVals [i] = getDefaultValue(items[1] || "nil");
    });
 
    wrapper = function() {
      var given, args;
 
      given = slice.call(arguments);
      args  = argVals.slice();
 
      if (isDictionary(given[given.length - 1])) {
        setKeywordArguments(args, argNames, given.pop());
      }
 
      copy(args, given, Math.min(argNames.length, given.length));
 
      if (remain) {
        args.push($.Array(given.slice(argNames.length)));
      }
 
      return func.apply(this, args);
    };
 
    wrapper._argNames = argNames;
    wrapper._argVals  = argVals;
 
    return wrapper;
  };
 
  function isDictionary(obj) {
    return !!(obj && obj.constructor === Object);
  }
 
  function copy(args, given, length) {
    for (var i = 0; i < length; ++i) {
      if (given[i]) {
        args[i] = given[i];
      }
    }
  }
 
  function _getDefaultValue(value) {
    var ch;
 
    switch (value) {
    case "nil":
      return $.Nil();
    case "true":
      return $.True();
    case "false":
      return $.False();
    case "inf":
      return $.Float(Infinity);
    case "-inf":
      return $.Float(-Infinity);
    }
 
    ch = value.charAt(0);
    switch (ch) {
    case "$":
      return $.Char(value.charAt(1));
    case "\\":
      return $.Symbol(value.substr(1));
    }
 
    if (value.indexOf(".") !== -1) {
      return $.Float(+value);
    }
 
    return $.Integer(+value);
  }
 
  function getDefaultValue(value) {
    if (value.charAt(0) === "[") {
      return $.Array(value.slice(1, -2).split(",").map(function(value) {
        return _getDefaultValue(value.trim());
      }));
    }
    return _getDefaultValue(value);
  }
 
  function setKeywordArguments(args, argNames, dict) {
    Object.keys(dict).forEach(function(key) {
      var index = argNames.indexOf(key);
      if (index !== -1) {
        args[index] = dict[key];
      }
    });
  }
 
  sc.lang.fn = fn;
})(sc);