Browse Source

Add functionality for referencing arguments with {}

Matt Coles 9 years ago
parent
commit
f880afa0c2
3 changed files with 55 additions and 1 deletions
  1. 46 0
      compiler.js
  2. 2 1
      examples/fizzbuzz.mc
  3. 7 0
      libjs/stdlib.js

+ 46 - 0
compiler.js

@@ -113,6 +113,15 @@ var tokenizer = function (input) {
113 113
       })
114 114
       continue
115 115
     }
116
+    let argv = /[{}]/
117
+    if (argv.test(char)) {
118
+      tokens.push({
119
+        type: 'argv',
120
+        value: char
121
+      })
122
+      pos++
123
+      continue
124
+    }
116 125
     throw new TypeError("I'm not sure what you are telling me :( Ask my creator to teach me what a: " + char + " is.")
117 126
   }
118 127
   return tokens
@@ -186,6 +195,28 @@ var parser = function (input) {
186 195
       return node
187 196
     }
188 197
 
198
+    if (token.type === 'argv' && token.value == '{') {
199
+      token = input[++pos]
200
+      if (token.type !== 'number') {
201
+        throw {
202
+          name: 'Compiler Error',
203
+          message: 'argv may only take integer values.'
204
+        }
205
+      }
206
+      let node = {
207
+        type: 'ArgvLiteral',
208
+        value: token.value
209
+      }
210
+      token = input[++pos]
211
+      if (token.type !== 'argv' || token.value !== '}') {
212
+        throw {
213
+          name: 'Compiler Error',
214
+          message: 'argv literals take one integer value and nothing else.'
215
+        }
216
+      }
217
+      pos++
218
+      return node
219
+    }
189 220
     throw new TypeError(token.type)
190 221
   }
191 222
 
@@ -231,6 +262,8 @@ var traverser = function (ast, visitor) {
231 262
         break
232 263
       case 'BarLiteral':
233 264
         break
265
+      case 'ArgvLiteral':
266
+        break
234 267
       default:
235 268
         throw {
236 269
           name: 'Compiler Error',
@@ -282,6 +315,12 @@ var transformer = function (ast) {
282 315
         value: node.value
283 316
       })
284 317
     },
318
+    ArgvLiteral: function (node, parent) {
319
+      parent._context.push({
320
+        type: 'ArgvLiteral',
321
+        value: node.value
322
+      })
323
+    },
285 324
     FunctionCall: function (node, parent) {
286 325
       let expression = {
287 326
         type: 'FunctionCall',
@@ -366,6 +405,13 @@ var generator = function (node) {
366 405
     case 'StringLiteral':
367 406
       return '{ value: \'' + node.value + '\' }'
368 407
       break
408
+    case 'ArgvLiteral':
409
+      if (node.value === 0) {
410
+        return '{ value: process.argv.slice(2).join(\' \') }'
411
+      } else {
412
+        return '_.__get_arg(' + (+node.value+1) + ')'
413
+      }
414
+      break
369 415
     default:
370 416
       throw {
371 417
         name: 'Compiler Error',

+ 2 - 1
examples/fizzbuzz.mc

@@ -11,4 +11,5 @@
11 11
   )
12 12
 1)
13 13
 
14
-(fizzbuzz 100)
14
+(if (eq {1} "")
15
+  (fizzbuzz 25) | (fizzbuzz {1}))

+ 7 - 0
libjs/stdlib.js

@@ -58,6 +58,13 @@ const builtins = {
58 58
   neg: function (pred) {
59 59
     return !pred
60 60
   },
61
+  __get_arg: function (arg) {
62
+    if (process.argv.length > arg) {
63
+      return { value: process.argv[arg] }
64
+    } else {
65
+      return { value: "" }
66
+    }
67
+  }
61 68
 }
62 69
 
63 70