• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..18-Jul-2019-

ast/H18-Jul-2019-2,0821,554

dbg/H18-Jul-2019-388265

file/H18-Jul-2019-276190

parser/H18-Jul-2019-3,9453,239

registry/H18-Jul-2019-10068

token/H18-Jul-2019-865711

.gitignoreH A D18-Jul-201960 65

DESIGN.markdownH A D18-Jul-201981 21

LICENSEH A D18-Jul-20191 KiB84

MakefileH A D18-Jul-20191.1 KiB6441

README.markdownH A D18-Jul-201919 KiB872626

builtin.goH A D18-Jul-20198.4 KiB355308

builtin_array.goH A D18-Jul-201919.2 KiB685600

builtin_boolean.goH A D18-Jul-2019719 2921

builtin_date.goH A D18-Jul-201915 KiB616507

builtin_error.goH A D18-Jul-20193.7 KiB12799

builtin_function.goH A D18-Jul-20193.6 KiB130106

builtin_json.goH A D18-Jul-20197.5 KiB300283

builtin_math.goH A D18-Jul-20193.5 KiB152129

builtin_number.goH A D18-Jul-20192.6 KiB9480

builtin_object.goH A D18-Jul-20197.4 KiB290256

builtin_regexp.goH A D18-Jul-20191.6 KiB6653

builtin_string.goH A D18-Jul-201913.5 KiB501417

clone.goH A D18-Jul-20194.2 KiB174150

cmpl.goH A D18-Jul-2019407 2520

cmpl_evaluate.goH A D18-Jul-20192.6 KiB9775

cmpl_evaluate_expression.goH A D18-Jul-201912.6 KiB461366

cmpl_evaluate_statement.goH A D18-Jul-201910.2 KiB425345

cmpl_parse.goH A D18-Jul-201914.8 KiB657553

console.goH A D18-Jul-2019993 5239

dbg.goH A D18-Jul-2019190 105

error.goH A D18-Jul-20194.8 KiB254202

evaluate.goH A D18-Jul-20198.1 KiB319261

global.goH A D18-Jul-20195.8 KiB222188

inline.goH A D18-Jul-2019133.9 KiB6,6506,630

inline.plH A D18-Jul-201925.9 KiB1,087979

object.goH A D18-Jul-20193.6 KiB157119

object_class.goH A D18-Jul-201911.2 KiB494422

otto.goH A D18-Jul-201920.3 KiB771314

otto_.goH A D18-Jul-20194 KiB179145

property.goH A D18-Jul-20195.3 KiB221180

result.goH A D18-Jul-2019495 3123

runtime.goH A D18-Jul-201920.7 KiB808670

scope.goH A D18-Jul-2019525 3617

script.goH A D18-Jul-20192.8 KiB12085

stash.goH A D18-Jul-20196.2 KiB297243

type_arguments.goH A D18-Jul-20192.9 KiB10785

type_array.goH A D18-Jul-20192.8 KiB110101

type_boolean.goH A D18-Jul-2019258 1410

type_date.goH A D18-Jul-20196 KiB300246

type_error.goH A D18-Jul-2019697 2521

type_function.goH A D18-Jul-20198.7 KiB341263

type_go_array.goH A D18-Jul-20193.1 KiB135113

type_go_map.goH A D18-Jul-20192.3 KiB9680

type_go_slice.goH A D18-Jul-20192.9 KiB127103

type_go_struct.goH A D18-Jul-20193.5 KiB147112

type_number.goH A D18-Jul-2019147 64

type_reference.goH A D18-Jul-20192.3 KiB10481

type_regexp.goH A D18-Jul-20194 KiB147127

type_string.goH A D18-Jul-20192.1 KiB11392

value.goH A D18-Jul-201926.1 KiB1,034801

value_boolean.goH A D18-Jul-2019793 4441

value_number.goH A D18-Jul-20196.5 KiB325290

value_primitive.goH A D18-Jul-2019582 2419

value_string.goH A D18-Jul-20192.5 KiB10492

README.markdown

1# otto
2--
3```go
4import "github.com/robertkrimen/otto"
5```
6
7Package otto is a JavaScript parser and interpreter written natively in Go.
8
9http://godoc.org/github.com/robertkrimen/otto
10
11```go
12import (
13   "github.com/robertkrimen/otto"
14)
15```
16
17Run something in the VM
18
19```go
20vm := otto.New()
21vm.Run(`
22    abc = 2 + 2;
23    console.log("The value of abc is " + abc); // 4
24`)
25```
26
27Get a value out of the VM
28
29```go
30if value, err := vm.Get("abc"); err == nil {
31    if value_int, err := value.ToInteger(); err == nil {
32	fmt.Printf("", value_int, err)
33    }
34}
35```
36
37Set a number
38
39```go
40vm.Set("def", 11)
41vm.Run(`
42    console.log("The value of def is " + def);
43    // The value of def is 11
44`)
45```
46
47Set a string
48
49```go
50vm.Set("xyzzy", "Nothing happens.")
51vm.Run(`
52    console.log(xyzzy.length); // 16
53`)
54```
55
56Get the value of an expression
57
58```go
59value, _ = vm.Run("xyzzy.length")
60{
61    // value is an int64 with a value of 16
62    value, _ := value.ToInteger()
63}
64```
65
66An error happens
67
68```go
69value, err = vm.Run("abcdefghijlmnopqrstuvwxyz.length")
70if err != nil {
71    // err = ReferenceError: abcdefghijlmnopqrstuvwxyz is not defined
72    // If there is an error, then value.IsUndefined() is true
73    ...
74}
75```
76
77Set a Go function
78
79```go
80vm.Set("sayHello", func(call otto.FunctionCall) otto.Value {
81    fmt.Printf("Hello, %s.\n", call.Argument(0).String())
82    return otto.Value{}
83})
84```
85
86Set a Go function that returns something useful
87
88```go
89vm.Set("twoPlus", func(call otto.FunctionCall) otto.Value {
90    right, _ := call.Argument(0).ToInteger()
91    result, _ := vm.ToValue(2 + right)
92    return result
93})
94```
95
96Use the functions in JavaScript
97
98```go
99result, _ = vm.Run(`
100    sayHello("Xyzzy");      // Hello, Xyzzy.
101    sayHello();             // Hello, undefined
102
103    result = twoPlus(2.0); // 4
104`)
105```
106
107### Parser
108
109A separate parser is available in the parser package if you're just interested
110in building an AST.
111
112http://godoc.org/github.com/robertkrimen/otto/parser
113
114Parse and return an AST
115
116```go
117filename := "" // A filename is optional
118src := `
119    // Sample xyzzy example
120    (function(){
121        if (3.14159 > 0) {
122            console.log("Hello, World.");
123            return;
124        }
125
126        var xyzzy = NaN;
127        console.log("Nothing happens.");
128        return xyzzy;
129    })();
130`
131
132// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
133program, err := parser.ParseFile(nil, filename, src, 0)
134```
135
136### otto
137
138You can run (Go) JavaScript from the commandline with:
139http://github.com/robertkrimen/otto/tree/master/otto
140
141    $ go get -v github.com/robertkrimen/otto/otto
142
143Run JavaScript by entering some source on stdin or by giving otto a filename:
144
145    $ otto example.js
146
147### underscore
148
149Optionally include the JavaScript utility-belt library, underscore, with this
150import:
151
152```go
153import (
154    "github.com/robertkrimen/otto"
155    _ "github.com/robertkrimen/otto/underscore"
156)
157
158// Now every otto runtime will come loaded with underscore
159```
160
161For more information: http://github.com/robertkrimen/otto/tree/master/underscore
162
163
164### Caveat Emptor
165
166The following are some limitations with otto:
167
168    * "use strict" will parse, but does nothing.
169    * The regular expression engine (re2/regexp) is not fully compatible with the ECMA5 specification.
170    * Otto targets ES5. ES6 features (eg: Typed Arrays) are not supported.
171
172
173### Regular Expression Incompatibility
174
175Go translates JavaScript-style regular expressions into something that is
176"regexp" compatible via `parser.TransformRegExp`. Unfortunately, RegExp requires
177backtracking for some patterns, and backtracking is not supported by the
178standard Go engine: https://code.google.com/p/re2/wiki/Syntax
179
180Therefore, the following syntax is incompatible:
181
182    (?=)  // Lookahead (positive), currently a parsing error
183    (?!)  // Lookahead (backhead), currently a parsing error
184    \1    // Backreference (\1, \2, \3, ...), currently a parsing error
185
186A brief discussion of these limitations: "Regexp (?!re)"
187https://groups.google.com/forum/?fromgroups=#%21topic/golang-nuts/7qgSDWPIh_E
188
189More information about re2: https://code.google.com/p/re2/
190
191In addition to the above, re2 (Go) has a different definition for \s: [\t\n\f\r
192]. The JavaScript definition, on the other hand, also includes \v, Unicode
193"Separator, Space", etc.
194
195
196### Halting Problem
197
198If you want to stop long running executions (like third-party code), you can use
199the interrupt channel to do this:
200
201```go
202package main
203
204import (
205    "errors"
206    "fmt"
207    "os"
208    "time"
209
210    "github.com/robertkrimen/otto"
211)
212
213var halt = errors.New("Stahp")
214
215func main() {
216    runUnsafe(`var abc = [];`)
217    runUnsafe(`
218    while (true) {
219        // Loop forever
220    }`)
221}
222
223func runUnsafe(unsafe string) {
224    start := time.Now()
225    defer func() {
226        duration := time.Since(start)
227        if caught := recover(); caught != nil {
228            if caught == halt {
229                fmt.Fprintf(os.Stderr, "Some code took to long! Stopping after: %v\n", duration)
230                return
231            }
232            panic(caught) // Something else happened, repanic!
233        }
234        fmt.Fprintf(os.Stderr, "Ran code successfully: %v\n", duration)
235    }()
236
237    vm := otto.New()
238    vm.Interrupt = make(chan func(), 1) // The buffer prevents blocking
239
240    go func() {
241        time.Sleep(2 * time.Second) // Stop after two seconds
242        vm.Interrupt <- func() {
243            panic(halt)
244        }
245    }()
246
247    vm.Run(unsafe) // Here be dragons (risky code)
248}
249```
250
251Where is setTimeout/setInterval?
252
253These timing functions are not actually part of the ECMA-262 specification.
254Typically, they belong to the `window` object (in the browser). It would not be
255difficult to provide something like these via Go, but you probably want to wrap
256otto in an event loop in that case.
257
258For an example of how this could be done in Go with otto, see natto:
259
260http://github.com/robertkrimen/natto
261
262Here is some more discussion of the issue:
263
264* http://book.mixu.net/node/ch2.html
265
266* http://en.wikipedia.org/wiki/Reentrancy_%28computing%29
267
268* http://aaroncrane.co.uk/2009/02/perl_safe_signals/
269
270## Usage
271
272```go
273var ErrVersion = errors.New("version mismatch")
274```
275
276#### type Error
277
278```go
279type Error struct {
280}
281```
282
283An Error represents a runtime error, e.g. a TypeError, a ReferenceError, etc.
284
285#### func (Error) Error
286
287```go
288func (err Error) Error() string
289```
290Error returns a description of the error
291
292    TypeError: 'def' is not a function
293
294#### func (Error) String
295
296```go
297func (err Error) String() string
298```
299String returns a description of the error and a trace of where the error
300occurred.
301
302    TypeError: 'def' is not a function
303        at xyz (<anonymous>:3:9)
304        at <anonymous>:7:1/
305
306#### type FunctionCall
307
308```go
309type FunctionCall struct {
310	This         Value
311	ArgumentList []Value
312	Otto         *Otto
313}
314```
315
316FunctionCall is an encapsulation of a JavaScript function call.
317
318#### func (FunctionCall) Argument
319
320```go
321func (self FunctionCall) Argument(index int) Value
322```
323Argument will return the value of the argument at the given index.
324
325If no such argument exists, undefined is returned.
326
327#### type Object
328
329```go
330type Object struct {
331}
332```
333
334Object is the representation of a JavaScript object.
335
336#### func (Object) Call
337
338```go
339func (self Object) Call(name string, argumentList ...interface{}) (Value, error)
340```
341Call a method on the object.
342
343It is essentially equivalent to:
344
345    var method, _ := object.Get(name)
346    method.Call(object, argumentList...)
347
348An undefined value and an error will result if:
349
350    1. There is an error during conversion of the argument list
351    2. The property is not actually a function
352    3. An (uncaught) exception is thrown
353
354#### func (Object) Class
355
356```go
357func (self Object) Class() string
358```
359Class will return the class string of the object.
360
361The return value will (generally) be one of:
362
363    Object
364    Function
365    Array
366    String
367    Number
368    Boolean
369    Date
370    RegExp
371
372#### func (Object) Get
373
374```go
375func (self Object) Get(name string) (Value, error)
376```
377Get the value of the property with the given name.
378
379#### func (Object) Keys
380
381```go
382func (self Object) Keys() []string
383```
384Get the keys for the object
385
386Equivalent to calling Object.keys on the object
387
388#### func (Object) Set
389
390```go
391func (self Object) Set(name string, value interface{}) error
392```
393Set the property of the given name to the given value.
394
395An error will result if the setting the property triggers an exception (i.e.
396read-only), or there is an error during conversion of the given value.
397
398#### func (Object) Value
399
400```go
401func (self Object) Value() Value
402```
403Value will return self as a value.
404
405#### type Otto
406
407```go
408type Otto struct {
409	// Interrupt is a channel for interrupting the runtime. You can use this to halt a long running execution, for example.
410	// See "Halting Problem" for more information.
411	Interrupt chan func()
412}
413```
414
415Otto is the representation of the JavaScript runtime. Each instance of Otto has
416a self-contained namespace.
417
418#### func  New
419
420```go
421func New() *Otto
422```
423New will allocate a new JavaScript runtime
424
425#### func  Run
426
427```go
428func Run(src interface{}) (*Otto, Value, error)
429```
430Run will allocate a new JavaScript runtime, run the given source on the
431allocated runtime, and return the runtime, resulting value, and error (if any).
432
433src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST
434always be in UTF-8.
435
436src may also be a Script.
437
438src may also be a Program, but if the AST has been modified, then runtime
439behavior is undefined.
440
441#### func (Otto) Call
442
443```go
444func (self Otto) Call(source string, this interface{}, argumentList ...interface{}) (Value, error)
445```
446Call the given JavaScript with a given this and arguments.
447
448If this is nil, then some special handling takes place to determine the proper
449this value, falling back to a "standard" invocation if necessary (where this is
450undefined).
451
452If source begins with "new " (A lowercase new followed by a space), then Call
453will invoke the function constructor rather than performing a function call. In
454this case, the this argument has no effect.
455
456```go
457// value is a String object
458value, _ := vm.Call("Object", nil, "Hello, World.")
459
460// Likewise...
461value, _ := vm.Call("new Object", nil, "Hello, World.")
462
463// This will perform a concat on the given array and return the result
464// value is [ 1, 2, 3, undefined, 4, 5, 6, 7, "abc" ]
465value, _ := vm.Call(`[ 1, 2, 3, undefined, 4 ].concat`, nil, 5, 6, 7, "abc")
466```
467
468#### func (*Otto) Compile
469
470```go
471func (self *Otto) Compile(filename string, src interface{}) (*Script, error)
472```
473Compile will parse the given source and return a Script value or nil and an
474error if there was a problem during compilation.
475
476```go
477script, err := vm.Compile("", `var abc; if (!abc) abc = 0; abc += 2; abc;`)
478vm.Run(script)
479```
480
481#### func (*Otto) Copy
482
483```go
484func (in *Otto) Copy() *Otto
485```
486Copy will create a copy/clone of the runtime.
487
488Copy is useful for saving some time when creating many similar runtimes.
489
490This method works by walking the original runtime and cloning each object,
491scope, stash, etc. into a new runtime.
492
493Be on the lookout for memory leaks or inadvertent sharing of resources.
494
495#### func (Otto) Get
496
497```go
498func (self Otto) Get(name string) (Value, error)
499```
500Get the value of the top-level binding of the given name.
501
502If there is an error (like the binding does not exist), then the value will be
503undefined.
504
505#### func (Otto) Object
506
507```go
508func (self Otto) Object(source string) (*Object, error)
509```
510Object will run the given source and return the result as an object.
511
512For example, accessing an existing object:
513
514```go
515object, _ := vm.Object(`Number`)
516```
517
518Or, creating a new object:
519
520```go
521object, _ := vm.Object(`({ xyzzy: "Nothing happens." })`)
522```
523
524Or, creating and assigning an object:
525
526```go
527object, _ := vm.Object(`xyzzy = {}`)
528object.Set("volume", 11)
529```
530
531If there is an error (like the source does not result in an object), then nil
532and an error is returned.
533
534#### func (Otto) Run
535
536```go
537func (self Otto) Run(src interface{}) (Value, error)
538```
539Run will run the given source (parsing it first if necessary), returning the
540resulting value and error (if any)
541
542src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST
543always be in UTF-8.
544
545If the runtime is unable to parse source, then this function will return
546undefined and the parse error (nothing will be evaluated in this case).
547
548src may also be a Script.
549
550src may also be a Program, but if the AST has been modified, then runtime
551behavior is undefined.
552
553#### func (Otto) Set
554
555```go
556func (self Otto) Set(name string, value interface{}) error
557```
558Set the top-level binding of the given name to the given value.
559
560Set will automatically apply ToValue to the given value in order to convert it
561to a JavaScript value (type Value).
562
563If there is an error (like the binding is read-only, or the ToValue conversion
564fails), then an error is returned.
565
566If the top-level binding does not exist, it will be created.
567
568#### func (Otto) ToValue
569
570```go
571func (self Otto) ToValue(value interface{}) (Value, error)
572```
573ToValue will convert an interface{} value to a value digestible by
574otto/JavaScript.
575
576#### type Script
577
578```go
579type Script struct {
580}
581```
582
583Script is a handle for some (reusable) JavaScript. Passing a Script value to a
584run method will evaluate the JavaScript.
585
586#### func (*Script) String
587
588```go
589func (self *Script) String() string
590```
591
592#### type Value
593
594```go
595type Value struct {
596}
597```
598
599Value is the representation of a JavaScript value.
600
601#### func  FalseValue
602
603```go
604func FalseValue() Value
605```
606FalseValue will return a value representing false.
607
608It is equivalent to:
609
610```go
611ToValue(false)
612```
613
614#### func  NaNValue
615
616```go
617func NaNValue() Value
618```
619NaNValue will return a value representing NaN.
620
621It is equivalent to:
622
623```go
624ToValue(math.NaN())
625```
626
627#### func  NullValue
628
629```go
630func NullValue() Value
631```
632NullValue will return a Value representing null.
633
634#### func  ToValue
635
636```go
637func ToValue(value interface{}) (Value, error)
638```
639ToValue will convert an interface{} value to a value digestible by
640otto/JavaScript
641
642This function will not work for advanced types (struct, map, slice/array, etc.)
643and you should use Otto.ToValue instead.
644
645#### func  TrueValue
646
647```go
648func TrueValue() Value
649```
650TrueValue will return a value representing true.
651
652It is equivalent to:
653
654```go
655ToValue(true)
656```
657
658#### func  UndefinedValue
659
660```go
661func UndefinedValue() Value
662```
663UndefinedValue will return a Value representing undefined.
664
665#### func (Value) Call
666
667```go
668func (value Value) Call(this Value, argumentList ...interface{}) (Value, error)
669```
670Call the value as a function with the given this value and argument list and
671return the result of invocation. It is essentially equivalent to:
672
673    value.apply(thisValue, argumentList)
674
675An undefined value and an error will result if:
676
677    1. There is an error during conversion of the argument list
678    2. The value is not actually a function
679    3. An (uncaught) exception is thrown
680
681#### func (Value) Class
682
683```go
684func (value Value) Class() string
685```
686Class will return the class string of the value or the empty string if value is
687not an object.
688
689The return value will (generally) be one of:
690
691    Object
692    Function
693    Array
694    String
695    Number
696    Boolean
697    Date
698    RegExp
699
700#### func (Value) Export
701
702```go
703func (self Value) Export() (interface{}, error)
704```
705Export will attempt to convert the value to a Go representation and return it
706via an interface{} kind.
707
708Export returns an error, but it will always be nil. It is present for backwards
709compatibility.
710
711If a reasonable conversion is not possible, then the original value is returned.
712
713    undefined   -> nil (FIXME?: Should be Value{})
714    null        -> nil
715    boolean     -> bool
716    number      -> A number type (int, float32, uint64, ...)
717    string      -> string
718    Array       -> []interface{}
719    Object      -> map[string]interface{}
720
721#### func (Value) IsBoolean
722
723```go
724func (value Value) IsBoolean() bool
725```
726IsBoolean will return true if value is a boolean (primitive).
727
728#### func (Value) IsDefined
729
730```go
731func (value Value) IsDefined() bool
732```
733IsDefined will return false if the value is undefined, and true otherwise.
734
735#### func (Value) IsFunction
736
737```go
738func (value Value) IsFunction() bool
739```
740IsFunction will return true if value is a function.
741
742#### func (Value) IsNaN
743
744```go
745func (value Value) IsNaN() bool
746```
747IsNaN will return true if value is NaN (or would convert to NaN).
748
749#### func (Value) IsNull
750
751```go
752func (value Value) IsNull() bool
753```
754IsNull will return true if the value is null, and false otherwise.
755
756#### func (Value) IsNumber
757
758```go
759func (value Value) IsNumber() bool
760```
761IsNumber will return true if value is a number (primitive).
762
763#### func (Value) IsObject
764
765```go
766func (value Value) IsObject() bool
767```
768IsObject will return true if value is an object.
769
770#### func (Value) IsPrimitive
771
772```go
773func (value Value) IsPrimitive() bool
774```
775IsPrimitive will return true if value is a primitive (any kind of primitive).
776
777#### func (Value) IsString
778
779```go
780func (value Value) IsString() bool
781```
782IsString will return true if value is a string (primitive).
783
784#### func (Value) IsUndefined
785
786```go
787func (value Value) IsUndefined() bool
788```
789IsUndefined will return true if the value is undefined, and false otherwise.
790
791#### func (Value) Object
792
793```go
794func (value Value) Object() *Object
795```
796Object will return the object of the value, or nil if value is not an object.
797
798This method will not do any implicit conversion. For example, calling this
799method on a string primitive value will not return a String object.
800
801#### func (Value) String
802
803```go
804func (value Value) String() string
805```
806String will return the value as a string.
807
808This method will make return the empty string if there is an error.
809
810#### func (Value) ToBoolean
811
812```go
813func (value Value) ToBoolean() (bool, error)
814```
815ToBoolean will convert the value to a boolean (bool).
816
817    ToValue(0).ToBoolean() => false
818    ToValue("").ToBoolean() => false
819    ToValue(true).ToBoolean() => true
820    ToValue(1).ToBoolean() => true
821    ToValue("Nothing happens").ToBoolean() => true
822
823If there is an error during the conversion process (like an uncaught exception),
824then the result will be false and an error.
825
826#### func (Value) ToFloat
827
828```go
829func (value Value) ToFloat() (float64, error)
830```
831ToFloat will convert the value to a number (float64).
832
833    ToValue(0).ToFloat() => 0.
834    ToValue(1.1).ToFloat() => 1.1
835    ToValue("11").ToFloat() => 11.
836
837If there is an error during the conversion process (like an uncaught exception),
838then the result will be 0 and an error.
839
840#### func (Value) ToInteger
841
842```go
843func (value Value) ToInteger() (int64, error)
844```
845ToInteger will convert the value to a number (int64).
846
847    ToValue(0).ToInteger() => 0
848    ToValue(1.1).ToInteger() => 1
849    ToValue("11").ToInteger() => 11
850
851If there is an error during the conversion process (like an uncaught exception),
852then the result will be 0 and an error.
853
854#### func (Value) ToString
855
856```go
857func (value Value) ToString() (string, error)
858```
859ToString will convert the value to a string (string).
860
861    ToValue(0).ToString() => "0"
862    ToValue(false).ToString() => "false"
863    ToValue(1.1).ToString() => "1.1"
864    ToValue("11").ToString() => "11"
865    ToValue('Nothing happens.').ToString() => "Nothing happens."
866
867If there is an error during the conversion process (like an uncaught exception),
868then the result will be the empty string ("") and an error.
869
870--
871**godocdown** http://github.com/robertkrimen/godocdown
872