1 ! Copyright (C) 2010 Slava Pestov.
2 USING: accessors kernel arrays strings math.parser peg peg.ebnf
3 multiline gml.types gml.runtime sequences sequences.deep locals
7 TUPLE: comment string ;
11 : register-index ( name registers -- n )
12 2dup index dup [ 2nip ] [ drop [ nip length ] [ push ] 2bi ] if ;
14 : resolve-register ( insn registers -- )
15 [ dup name>> ] dip register-index >>n drop ;
17 ERROR: missing-usereg ;
19 :: (resolve-registers) ( array registers -- ? )
23 { [ dup use-registers? ] [ use-registers! ] }
24 { [ dup read-register? ] [ registers resolve-register ] }
25 { [ dup exec-register? ] [ registers resolve-register ] }
26 { [ dup write-register? ] [ registers resolve-register ] }
28 dup [ use-registers? ] any? [ drop ] [
29 array>> registers (resolve-registers) drop
37 :: resolve-registers ( array -- )
38 V{ } clone :> registers
39 array [ use-registers? ] any? [
40 array registers (resolve-registers)
41 registers length >>n drop
44 : parse-proc ( array -- proc )
45 >array [ resolve-registers ] [ { } <proc> ] bi ;
47 ERROR: bad-vector-length seq n ;
49 : parse-vector ( seq -- vec )
51 { 2 [ first2 <vec2d> ] }
52 { 3 [ first3 <vec3d> ] }
62 Sign = ('+' => [[ first ]]|'-' => [[ first ]])?
64 StopChar = ('('|')'|'['|']'|'{'|'}'|'/'|'/'|';'|':'|'!'|'.')
68 Spaces = Space* => [[ ignore ]]
72 Number = Sign Digit+ ('.' => [[ first ]] Digit+)? ('e' => [[ first ]] Sign Digit+)?
73 => [[ flatten sift >string string>number ]]
75 VectorComponents = (Number:f Spaces ',' Spaces => [[ f ]])*:fs Number:f Spaces => [[ fs f suffix ]]
77 Vector = '(' Spaces VectorComponents ')' => [[ second parse-vector ]]
81 String = '"' StringChar+:s '"' => [[ s >string ]]
83 NameChar = !(Space|StopChar).
85 Name = NameChar+ => [[ >string ]]
87 Comment = ('%' (!(Newline) .)* (Newline|!(.))) => [[ <comment> ]]
89 ArrayStart = '[' => [[ marker ]]
91 ArrayEnd = ']' => [[ exec" ]" ]]
93 ExecArray = '{' Token*:ts Spaces '}' => [[ ts parse-proc ]]
95 LiteralName = '/' Name:n => [[ n >gml-name ]]
97 UseReg = "usereg" !(NameChar) => [[ <use-registers> ]]
99 ReadReg = ";" Name:n => [[ n <read-register> ]]
100 ExecReg = ":" Name:n => [[ n <exec-register> ]]
101 WriteReg = "!" Name:n => [[ n <write-register> ]]
103 ExecName = Name:n => [[ n >gml-exec-name ]]
105 PathNameComponent = "." Name:n => [[ n >gml-name ]]
106 PathName = PathNameComponent+ => [[ <pathname> ]]
124 Tokens = Token* => [[ [ comment? ] reject ]]
126 Program = Tokens Spaces !(.) => [[ parse-proc ]]