рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ! рдореИрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ - рдкреАрдПрд▓ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧрд╛рдЗрдб рдХрд╛ рдПрдХ рд╢реМрдХрд┐рдпрд╛ рдЕрдиреБрд╡рд╛рдж рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВред
рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ
рд╣рдо рдЕрдкрдиреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ - ╬╗ рднрд╛рд╖рд╛ (рдореВрд▓ - ╬╗anguage рдореЗрдВ) рдмрдирд╛рдПрдВрдЧреЗред рдирд┐рд░реНрдорд╛рдг рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╣рдо рдХрдИ рджрд┐рд▓рдЪрд╕реНрдк рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреИрд╕реЗ рдХрд┐ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╡рдВрд╢, рдирд┐рдпрдВрддреНрд░рдг рд╣рд╕реНрддрд╛рдВрддрд░рдг рд╢реИрд▓реА, рдФрд░ рдмреБрдирд┐рдпрд╛рджреА рдЕрдиреБрдХреВрд▓рди рддрдХрдиреАрдХред рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдг рдмрдирд╛рдП рдЬрд╛рдПрдВрдЧреЗ - рдирд┐рдпрдорд┐рдд рдФрд░ рд╕реАрдкреАрдПрд╕ рджреБрднрд╛рд╖рд┐рдпреЛрдВ, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯреНрд░рд╛рдВрд╕-рдХрдВрдкрд╛рдЗрд▓рд░ред
рдореВрд▓ рдХреЗ рд▓реЗрдЦрдХ рдорд┐рд╣рд╛рдИ Bazon , рдкреНрд░рд╕рд┐рджреНрдз UglifyJS рдкреБрд╕реНрддрдХрд╛рд▓рдп (рдЬреЗрдПрд╕ рдХреЛрдб рдХреЛ рдХрдо рдХрд░рдиреЗ рдФрд░ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрдкрдХрд░рдг) рдХреЗ рд▓реЗрдЦрдХ рд╣реИрдВред
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐
рдпрджрд┐ рдЖрдкрдиреЗ рдХрднреА рдЕрдкрдирд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╛ рджреБрднрд╛рд╖рд┐рдпрд╛ рд▓рд┐рдЦрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЗ рд▓рд┐рдП рдХреЛрдИ рдирдИ рдмрд╛рдд рдирд╣реАрдВ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреА рддрд░рд╣ рджрд┐рдЦрдиреЗ рд╡рд╛рд▓реА рдЪреАрдЬрд╝ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдкрд░ рдЕрдиреБрднрд╛рдЧ рдкрдврд╝реЗрдВред рдХрдо рдмрдЧ рдХреЗ рд╕рд╛рде рдХреЛрдб рд▓рд┐рдЦреЗрдВ!
"рд╕рд░рд▓ рд╕реЗ рдЬрдЯрд┐рд▓" рдХреНрд░рдо рдореЗрдВ рд▓реЗрдЦ рдХреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рд▓реЗрдЦ рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ, рдЬрдм рддрдХ рдХрд┐ рдЖрдк рд╡рд┐рд╖рдп рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд╣реАрдВ рд╕рдордЭрддреЗ рд╣реИрдВред рдЕрдЧрд░ рдЖрдкрдХреЛ рдХреБрдЫ рд╕рдордЭ рдирд╣реАрдВ рдЖ рд░рд╣рд╛ рд╣реИ рддреЛ рдЖрдк рд╣рдореЗрд╢рд╛ рдкреАрдЫреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдо рдХреНрдпрд╛ рд╕реАрдЦрдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ:
- рдПрдХ рдкрд╛рд░реНрд╕рд░ рдХреНрдпрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИред
- рдЗрдВрдЯрд░рдкреНрд░реЗрдЯрд░ рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВред
- рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреА рдЕрдЧрд▓реА рдХрдбрд╝реА, рдФрд░ рдпрд╣ рдХреНрдпреЛрдВ рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИред
- (рдЯреНрд░рд╛рдВрд╕) рд╕рдВрдХрд▓рдХ рд▓реЗрдЦрдиред
- рдирд┐рд░рдВрддрд░рддрд╛ рд╣рд╕реНрддрд╛рдВрддрд░рдг рд╢реИрд▓реАред
- рдХреБрдЫ рдмреБрдирд┐рдпрд╛рджреА рдХреЛрдб рдЕрдиреБрдХреВрд▓рди рддрдХрдиреАрдХред
- рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╣рдорд╛рд░реА ╬╗ рднрд╛рд╖рд╛ рдореЗрдВ рдХреНрдпрд╛ рдирдпрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдгред
рдЗрд╕рдХреЗ рд╕рд╛рде, рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рд▓рд┐рд╕реНрдк рдПрдХ рдорд╣рд╛рди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреНрдпреЛрдВ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдо рдЬрд┐рд╕ рднрд╛рд╖рд╛ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╡рд╣ рд▓рд┐рд╕реНрдк рдирд╣реАрдВ рд╣реИред рдЗрд╕рдореЗрдВ рд░рд┐рдЪ рд╕рд┐рдВрдЯреИрдХреНрд╕ (рдПрдХ рдХреНрд▓рд╛рд╕рд┐рдХ рдЗрдиреНрдлрд┐рдХреНрд╕ рдиреЛрдЯреЗрд╢рди рдЬрд┐рд╕реЗ рд╣рд░ рдХреЛрдИ рдЬрд╛рдирддрд╛ рд╣реИ), рд╕реНрдХреАрдо (рдореИрдХреНрд░реЛрдЬрд╝ рдХреЛ рдЫреЛрдбрд╝рдХрд░) рдЬреИрд╕реА рдХреБрдЫ рд╣реИред рдЕрдЪреНрдЫреА рдпрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдореИрдХреНрд░реЛрдЬрд╝ рд▓рд┐рд╕реНрдк рдХреА рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ - рдРрд╕рд╛ рдХреБрдЫ рдЬреЛ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ (рд▓рд┐рд╕реНрдк рдмреЛрд▓рд┐рдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░) рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред (рд╣рд╛рдВ, рдореБрдЭреЗ SweetJS рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рд╣реИ ... рдХрд░реАрдм рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред)
рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдЖрдЗрдП рд╣рдорд╛рд░реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрдВред
╬╗ рднрд╛рд╖рд╛
рдХреБрдЫ рднреА рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реНрдкрд╖реНрдЯ рддрд╕реНрд╡реАрд░ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рднрд╛рд╖рд╛ рдХреЗ рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рд╡рд░реНрдгрди рд▓рд┐рдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ - рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦреЗрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдВ ╬╗ рднрд╛рд╖рд╛ рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рджрд┐рдП рдЧрдП рд╣реИрдВ:
рдЪрд░ рдирд╛рдо рдкрд░ рдзреНрдпрд╛рди рджреЗрдВрдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдореЗрдВ рдЛрдг рдЪрд┐рд╣реНрди ( print-range
) рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╕реНрд╡рд╛рдж рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИред рдореИрдВ рд╣рдореЗрд╢рд╛ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рд░рдЦрддрд╛ рд╣реВрдВред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрдорд▓рд░рд┐рдЬрд┐рд╕реНрдЯрд░ рдФрд░ рдбреИрд╢ рдХреЛ рдЕрджреГрд╢реНрдп рд╕реНрдерд╛рди ("_") рд╕реЗ рдмреЗрд╣рддрд░ рдирд╣реАрдВ рдорд╛рдирддрд╛ред рдЬрдм рдЖрдк рдЦреБрдж рдХреБрдЫ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдк рдХрд┐рддрдирд╛ рд╢рд╛рдВрдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд╖реНрдХрд░реНрд╖:
Hello World! 14 610 1, 2, 3, 4, 5
рднрд╛рд╖рд╛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ рдпрд╣ рдирд╣реАрдВ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдХреЛрдИ рдмрдпрд╛рди рдирд╣реАрдВ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ред рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдПрдХ рдореВрд▓реНрдп рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдХрд┐рд╕реА рдЕрдиреНрдп рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдХрд╣реАрдВ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ "рдЕрдиреБрдХреНрд░рдо" рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдШреБрдВрдШрд░рд╛рд▓реЗ рдмреНрд░реЗрд╕реЗрд╕ {
рдФрд░ }
рдПрдХ рдЕрдиреБрдХреНрд░рдо рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрд╡рдпрдВ рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдорд╛рди рдЕрдиреБрдХреНрд░рдо рд╕реЗ рдЕрдВрддрд┐рдо рдорд╛рди рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕рд╣реА рд╣реИ:
a = { fib(10);
lambda
рдпрд╛ ╬╗
рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рд░реНрдп рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдХреЛрд╖реНрдардХ рдореЗрдВ рддрд░реНрдХ рдирд╛рдореЛрдВ рдХреА рдПрдХ (рд╕рдВрднрд╡рддрдГ рдЦрд╛рд▓реА) рд╕реВрдЪреА рд╣реИ, рдЬреЛ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХреА рдЬрд╛рддреА рд╣реИред рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╢рд░реАрд░ рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ {...}
ред рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдХреЛрдИ return
рдХреАрд╡рд░реНрдб рдирд╣реАрдВ рд╣реИред рдлрд╝рдВрдХреНрд╢рди рдЕрдВрддрд┐рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреЛрдИ var
рдирд╣реАрдВред рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ IIFE
рдХреНрдпрд╛ рдХрд╣рддреЗ рд╣реИрдВред lambda
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЪрд░ рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВред рдЪрд░реЛрдВ рдХреЗ рд▓рд┐рдП, рджрд╛рдпрд░рд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреНрд▓реЛрдЬрд░ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ [рд▓рдЧрднрдЧред рдЕрдиреБрд╡рд╛рдж: ES6 рддрдХ]ред
рднрд▓реЗ if
рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд░реНрдирд░реА рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:
a = foo() ? bar() : baz(); // JavaScript a = if foo() then bar() else baz();
then
рдХреАрд╡рд░реНрдб рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ рдпрджрд┐ рд╢рд╛рдЦрд╛ рдПрдХ рдЕрдиреБрдХреНрд░рдо ( {...}
) рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдКрдкрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХ рдЕрдиреНрдп рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╡реИрдХрд▓реНрдкрд┐рдХ рд╢рд╛рдЦрд╛ рдореМрдЬреВрдж рд╣реЛрдиреЗ рдкрд░ else
рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдлрд┐рд░, then
рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рд╢рд░реАрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк {...}
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрдИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдПрдХ рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ else
рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реИ рдФрд░ рд╕реНрдерд┐рддрд┐ false
, рддреЛ рд╕рднреА рдХрд╛ рдкрд░рд┐рдгрд╛рдо false
ред рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ false
рдПрдХ рдХреАрд╡рд░реНрдб рд╣реИ рдЬреЛ рдПрдХ рдорд╛рди рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдПрдХ ╬╗ рднрд╛рд╖рд╛ рдореЗрдВ рдПрдХрдорд╛рддреНрд░ рдЧрд▓рдд рдорд╛рди рд╣реИ:
if foo() then print("OK");
рдЙрддреНрдкрд╛рджрди OK
рдЕрдЧрд░ рдФрд░ рдХреЗрд╡рд▓ рдЕрдЧрд░ foo()
рдкрд░рд┐рдгрд╛рдо false
рдирд╣реАрдВ false
ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд╣рд╛рдБ рдХреАрд╡рд░реНрдб true
, рд▓реЗрдХрд┐рди рдмрд┐рд▓реНрдХреБрд▓ рд╕рдм рдХреБрдЫ рдЬреЛ false
рдирд╣реАрдВ false
(рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рднреАрддрд░, рдСрдкрд░реЗрдЯрд░ ===
) рд╢рд╛рдЦрд╛рдУрдВ рдореЗрдВ true
рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ (рдирдВрдмрд░ 0
рдФрд░ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рд╣рд┐рдд ""
)ред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ if
рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреЛрд╖реНрдардХ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдПрдХ рдЧрд▓рддреА рдирд╣реАрдВ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ (
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╡реЗ рд╕рд┐рд░реНрдл рд╕рддрд╣реА рд╣реИрдВред
рд╕рдВрдкреВрд░реНрдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рддрдм рднреА рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рд╡рд╣ рдХреЛрд╖реНрдардХреЛрдВ рд╕реЗ рдШрд┐рд░рд╛ рд╣реЛ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП ;
рдкреНрд░рддреНрдпреЗрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрд╛рджред рдЕрдВрддрд┐рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдПрдХ рдЕрдкрд╡рд╛рдж рд╣реИред
рдорд╣рд╛рди, рдпрд╣ рд╣рдорд╛рд░реА рдЫреЛрдЯреА ╬╗ рднрд╛рд╖рд╛ рд╣реИред рд╡рд╣ рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИред рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╕реБрдВрджрд░ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рджреЛрд╖ рд╣реИрдВред рдХрдИ рдЕрдиреБрдкрд▓рдмреНрдз рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ, рдЬреИрд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдФрд░ рд╕рд░рдгрд┐рдпрд╛рдБред рд╣рдо рдЙрди рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╣рдорд╛рд░реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдирд╣реАрдВ рд╣реИрдВред
рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдкрдиреА рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░реНрд╕рд░ рд▓рд┐рдЦреЗрдВрдЧреЗред
рдПрдПрд╕рдЯреА рдХреЗ рд▓рд┐рдП рдХреЛрдб рд░реВрдкрд╛рдВрддрд░рдг
рдПрдХ рдкрд╛рд░реНрд╕рд░ рдмрдирд╛рдирд╛ рдПрдХ рдореБрд╢реНрдХрд┐рд▓ рдХрд╛рдо рд╣реИред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЗрд╕реЗ рдХреЛрдб рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕реЗ рдПрдПрд╕рдЯреА (рд╕рд╛рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА) рдореЗрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред рдПрдПрд╕рдЯреА рд╕реНрдореГрддрд┐ рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдПрдХ рд╕рдВрд░рдЪрд┐рдд рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╣реИ, рд╕рд╛рд░ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрд░реА рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИ, рдХреЗрд╡рд▓ рд╢рдмреНрджрд╛рд░реНрдеред рд╡рд┐рд╡рд░рдг рдПрдПрд╕рдЯреА рдПрдХ рдЕрд▓рдЧ рднрд╛рдЧ рдореЗрдВ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╣реИрдВ:
sum = lambda(a, b) { a + b; }; print(sum(1, 2));
рд╣рдорд╛рд░рд╛ рдкрд╛рд░реНрд╕рд░ рдПрдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкреЗрдбрд╝ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛:
{ type: "prog", prog: [
рдкрд╛рд░реНрд╕рд░ рдмрдирд╛рдиреЗ рдореЗрдВ рдореБрдЦреНрдп рдХрдард┐рдирд╛рдИ рдХреЛрдб рдХреЛ рдареАрдХ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдХрдард┐рдирд╛рдИ рд╣реИред рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рд╡рд░реНрдг рдкрдврд╝рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкрд╛рд░реНрд╕рд░ рдХреЛ рдЙрдЪреНрдЪ рд╕реНрддрд░ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреЛрдб рдЬрдЯрд┐рд▓рддрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рджрд┐рд╢рд╛рдирд┐рд░реНрджреЗрд╢:
- рдмрд╣реБрдд рд╕рд╛рд░реА рдЫреЛрдЯреА рдЫреЛрдЯреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рд▓рд┐рдЦрд┐рдПред рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдПрдХ рдХрд╛рдо рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд░реЗрдВред
- рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХрд░реЗрдВред рд╡реЗ рд╕рд┐рд░реНрдл рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗред рд╡реЗ рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди, рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред
- рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рди рдХрд░реЗрдВред рдЬрдм рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЛ рдкрд╛рд░реНрд╕ рдХреИрд╕реЗ рдХрд░реЗрдВ, рддреЛ рддреНрд░реБрдЯрд┐ (рдкрдВрдХреНрддрд┐ рдФрд░ рд╕реНрддрдВрдн) рдХреЗ рд╕реНрдерд╛рди рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджреЗрдВред
рдХреЛрдб рдХреЛ рд╕рд░рд▓ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ рддреАрди рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рдХрдИ рдЫреЛрдЯреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИрдВ:
рдЪрд░рд┐рддреНрд░ рдХреА рдзрд╛рд░рд╛
рдпрд╣ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рд╣рдо рдПрдХ рд╕реНрдЯреНрд░реАрдо рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВрдЧреЗ рдЬреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдкрдврд╝рдиреЗ рд╡рд╛рд▓реЗ рдкрд╛рддреНрд░реЛрдВ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░реЗрдЧрд╛ред рдЗрд╕рдореЗрдВ рдЪрд╛рд░ рдХрд╛рд░реНрдп рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:
peek()
- рдзрд╛рд░рд╛ рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдмрд┐рдирд╛ рдЕрдЧрд▓рд╛ рд╡рд░реНрдг рд▓реМрдЯрд╛рддрд╛ рд╣реИредnext()
- рдзрд╛рд░рд╛ рд╕реЗ рдирд┐рдХрд╛рд▓рддреЗ рд╣реБрдП, рдЕрдЧрд▓рд╛ рд╡рд░реНрдг рд▓реМрдЯрд╛рддрд╛ рд╣реИредeof()
- рдпрджрд┐ рдзрд╛рд░рд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд░реНрдг рдирд╣реАрдВ рд╣реИрдВ рддреЛ рдпрд╣ true
рд╣реИредcroak(msg)
- рд╕рдВрджреЗрд╢ ( msg
) рдФрд░ рдзрд╛рд░рд╛ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рд╡рд╛рд▓реЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрддрд╛ рд╣реИред
рдЕрдВрддрд┐рдо рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдк рддреНрд░реБрдЯрд┐ рдХреЗ рд╕реНрдерд╛рди рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рд╕рдХреЗрдВред
рдпрд╣рд╛рдБ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдкреВрд░рд╛ рдХреЛрдб рд╣реИ (рдЪрд▓реЛ рдЗрд╕реЗ InputStream
рдХрд╣рддреЗ рд╣реИрдВ)ред рдпрд╣ рдХрд╛рдлреА рдЫреЛрдЯрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП:
function InputStream(input) { var pos = 0, line = 1, col = 0; return { next : next, peek : peek, eof : eof, croak : croak, }; function next() { var ch = input.charAt(pos++); if (ch == "\n") line++, col = 0; else col++; return ch; } function peek() { return input.charAt(pos); } function eof() { return peek() == ""; } function croak(msg) { throw new Error(msg + " (" + line + ":" + col + ")"); } }
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд╕реНрддреБ рдирд╣реАрдВ рд╣реИ (рдЬреЛ new
рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрдирд╛рдИ рдЧрдИ рд╣реИ)ред рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: var stream = InputStream(string)
ред
рдЕрдЧрд▓рд╛, рд╣рдо рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрддрд░ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗ: рдЯреЛрдХрди рдкреНрд░рд╡рд╛рд╣ (рдЯреЛрдХрди) ред
рдЯреЛрдХрди рдкреНрд░рд╡рд╛рд╣ (рдЯреЛрдХрди)
рдЯреЛрдХреЗрдирд╛рдЗрдЬрд╝рд░ (lexer) рд╡рд░реНрдгреЛрдВ рдХреА рдПрдХ рдзрд╛рд░рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╣реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди peek()
/ next()
рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдЯреЛрдХрди рд╣реЛрдВрдЧреЗред рдПрдХ рдЯреЛрдХрди рджреЛ рдЧреБрдгреЛрдВ рд╡рд╛рд▓рд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ: type
, value
ред рдпрд╣рд╛рдБ рдЯреЛрдХрди рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рджрд┐рдП рдЧрдП рд╣реИрдВ:
{ type: "punc", value: "(" }
рд╡реНрд╣рд╛рдЯреНрд╕рдПрдк (рд╕реНрдкреЗрд╕, рдЯреИрдм, рд▓рд╛рдЗрди рдмреНрд░реЗрдХ) рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдмрд╕ рдЫреЛрдбрд╝ рджреА рдЬрд╛рддреА рд╣реИрдВред
рдПрдХ рдЯреЛрдХрди рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреА рднрд╛рд╖рд╛ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИред рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдЪрд░рд┐рддреНрд░ ( input.peek()
) рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣рдо рдпрд╣ рддрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреМрди рд╕рд╛ рдЯреЛрдХрди рдкрдврд╝рдирд╛ рд╣реИ:
- рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡реНрд╣рд╛рдЯреНрд╕рдПрдк рдХреЛ рд╕реНрдХрд┐рдк рдХрд░реЗрдВред
- рдпрджрд┐
input.eof()
, рддреЛ null
рд▓реМрдЯреЗрдВред - рдпрджрд┐ рдпрд╣
#
рд╡рд░реНрдг рд╣реИ, рддреЛ рд╕рднреА рд╡рд░реНрдгреЛрдВ рдХреЛ рдкрдВрдХреНрддрд┐ рдХреЗ рдЕрдВрдд рддрдХ рдЫреЛрдбрд╝реЗрдВ (рдФрд░ рдЕрдЧрд▓рд╛ рдЯреЛрдХрди рд▓реМрдЯрд╛рдПрдВ)ред - рдпрджрд┐ рдпрд╣ рдПрдХ рдЙрджреНрдзрд░рдг рдЪрд┐рд╣реНрди рд╣реИ, рддреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрдврд╝реЗрдВред
- рдпрджрд┐ рдпрд╣ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИ, рддреЛ рд╕рдВрдЦреНрдпрд╛ рдкрдврд╝реЗрдВред
- рдпрджрд┐ рдпрд╣ рдПрдХ рдкрддреНрд░ рд╣реИ, рддреЛ рд╣рдо рд╢рдмреНрдж рдкрдврд╝рддреЗ рд╣реИрдВ, рдФрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдпрд╛ рдХреАрд╡рд░реНрдб рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред
- рдпрджрд┐ рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рдЯреЛрдХрди рд▓реМрдЯрд╛рдПрдВред
- рдпрджрд┐ рдпрд╣ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рдкреНрд░рддреАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рддреЛ рд╣рдо рд╕рдВрдмрдВрдзрд┐рдд рдЯреЛрдХрди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
- рдпрджрд┐ рдЙрдкрд░реЛрдХреНрдд рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ
input.croak()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджреЗрдВред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ tokenizer рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп read_next
рдлрд╝рдВрдХреНрд╢рди рд╣реЛрдЧрд╛:
function read_next() { read_while(is_whitespace); if (input.eof()) return null; var ch = input.peek(); if (ch == "#") { skip_comment(); return read_next(); } if (ch == '"') return read_string(); if (is_digit(ch)) return read_number(); if (is_id_start(ch)) return read_ident(); if (is_punc(ch)) return { type : "punc", value : input.next() }; if (is_op_char(ch)) return { type : "op", value : read_while(is_op_char) }; input.croak("Can't handle character: " + ch); }
рдпрд╣рд╛рдВ рдЖрдк рдХрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдлрд╝рдВрдХреНрд╢рди рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреЛрдХрди read_string()
, рдЬреИрд╕реЗ рдХрд┐ read_string()
, read_number()
, рдЖрджрд┐ ... рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрд╛рдХрд┐ рдХреЛрдб рд╕рд░рд▓ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рджрд┐рдЦрд╛рдИ рджреЗред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рд╣реА рдмрд╛рд░ рдореЗрдВ рд╕рднреА рдкреНрд░рддреАрдХреЛрдВ рдХреЛ рджреВрд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ: рд╣рд░ рдмрд╛рд░ рдЬрдм рдкрд╛рд░реНрд╕рд░ рдЕрдЧрд▓реЗ рдЯреЛрдХрди рдХреЗ рд▓рд┐рдП рдкреВрдЫрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдЯреЛрдХрди рдкрдврд╝реЗрдВрдЧреЗред рдпрджрд┐ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдЧрд▓рддреА рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдордиреЗ рд╕рднреА рдкрд╛рддреНрд░реЛрдВ рдХреЛ рдкрдврд╝рд╛ рднреА рдирд╣реАрдВ рд╣реИред
read_ident()
рд╕рднреА рд╡рд░реНрдгреЛрдВ рдХреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ is_id()
рдЬреЛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ ( is_id()
) рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдкрддреНрд░, ╬╗
, рдпрд╛ _
рд╢реБрд░реВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рд╣реА рд╡рд░реНрдг, рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рдХреЛрдИ рднреА рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: ?!-<>=
ред рдпрд╣ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ рдХрд┐ foo-bar
рдХреЛ рддреАрди рдЯреЛрдХрди рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдкрдврд╝рд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдПрдХ рдХреЗ рд░реВрдк рдореЗрдВ ( var
рдЯреЛрдХрди)ред рдХреНрдпрд╛ рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХреЗ is-pair?
рд░реВрдк is-pair?
рдирд╛рдо рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ is-pair?
рдпрд╛ string>=
(рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдпрд╣ рдореЗрд░реЗ рдореЗрдВ рд▓рд┐рд╕реНрдкрд░ рд╣реИ)ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, read_ident()
рдпрд╣ рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдЬреНрдЮрд╛рдд рдХреАрд╡рд░реНрдб рдХреА рд╕реВрдЪреА рдореЗрдВ рдХреЛрдИ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдпрд╣ рд╣реИ, рддреЛ рдПрдХ var
-token рдХреЛ var
-token рдХреЗ рдмрдЬрд╛рдп рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рдЦреБрдж рдХреЗ рд▓рд┐рдП рдмреЛрд▓рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдВ рд╣рдорд╛рд░реА рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рддреИрдпрд╛рд░ рдЯреЛрдХрди рд╣реИ:
рдкреВрд░рд╛ рдХреЛрдб function TokenStream(input) { var current = null; var keywords = " if then else lambda ╬╗ true false "; return { next : next, peek : peek, eof : eof, croak : input.croak }; function is_keyword(x) { return keywords.indexOf(" " + x + " ") >= 0; } function is_digit(ch) { return /[0-9]/i.test(ch); } function is_id_start(ch) { return /[a-z╬╗_]/i.test(ch); } function is_id(ch) { return is_id_start(ch) || "?!-<>=0123456789".indexOf(ch) >= 0; } function is_op_char(ch) { return "+-*/%=&|<>!".indexOf(ch) >= 0; } function is_punc(ch) { return ",;(){}[]".indexOf(ch) >= 0; } function is_whitespace(ch) { return " \t\n".indexOf(ch) >= 0; } function read_while(predicate) { var str = ""; while (!input.eof() && predicate(input.peek())) str += input.next(); return str; } function read_number() { var has_dot = false; var number = read_while(function(ch){ if (ch == ".") { if (has_dot) return false; has_dot = true; return true; } return is_digit(ch); }); return { type: "num", value: parseFloat(number) }; } function read_ident() { var id = read_while(is_id); return { type : is_keyword(id) ? "kw" : "var", value : id }; } function read_escaped(end) { var escaped = false, str = ""; input.next(); while (!input.eof()) { var ch = input.next(); if (escaped) { str += ch; escaped = false; } else if (ch == "\\") { escaped = true; } else if (ch == end) { break; } else { str += ch; } } return str; } function read_string() { return { type: "str", value: read_escaped('"') }; } function skip_comment() { read_while(function(ch){ return ch != "\n" }); input.next(); } function read_next() { read_while(is_whitespace); if (input.eof()) return null; var ch = input.peek(); if (ch == "#") { skip_comment(); return read_next(); } if (ch == '"') return read_string(); if (is_digit(ch)) return read_number(); if (is_id_start(ch)) return read_ident(); if (is_punc(ch)) return { type : "punc", value : input.next() }; if (is_op_char(ch)) return { type : "op", value : read_while(is_op_char) }; input.croak("Can't handle character: " + ch); } function peek() { return current || (current = read_next()); } function next() { var tok = current; current = null; return tok || read_next(); } function eof() { return peek() == null; } }
next()
рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрд╢рд╛ read_next()
рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдЯреЛрдХрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдкрд╣рд▓реЗ рдкрдврд╝рд╛ рдЧрдпрд╛ рд╣реЛ ( peek()
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)ред рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ current
рдЪрд░ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рд╢рд╛рдорд┐рд▓ рд╣реИред- рдХреЗрд╡рд▓ рджрд╢рдорд▓рд╡ рд╕рдВрдЦреНрдпрд╛ рдирд┐рдпрдорд┐рдд рд╕рдВрдХреЗрддрди рдореЗрдВ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ (1E5, 0x, рдЖрджрд┐ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИрдВ)ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо рдЙрдирдХрд╛ рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХреЗрд╡рд▓
read_number()
ред - рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдХреЗрд╡рд▓ рд╡рд░реНрдг рдЬреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдЕрдирд╕реИрдкреНрдб рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджреНрдзрд░рдг рдЪрд┐рд╣реНрди рдФрд░ рдмреИрдХрд▓реИрд╢ рд╣реИрдВред рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рд▓рд╛рдЗрди рдмреНрд░реЗрдХ, рдЯреИрдм рдФрд░ рдХреБрдЫ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдорд╛рдирдХ рд╕рдВрдпреЛрдЬрдиреЛрдВ рдЬреИрд╕реЗ
\n
, \t
, рдЖрджрд┐ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ ... рдпрд╣ рдлрд┐рд░ рд╕реЗ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ ( read_string()
)ред
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рдкрд╛рд░реНрд╕рд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рдореИрдВ рдПрдПрд╕рдЯреА рд╡рд┐рд╡рд░рдг рдХреЛ рджреЗрдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреВрдВрдЧрд╛ ред
рдПрдПрд╕рдЯреА рд╡рд┐рд╡рд░рдг
рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдкрд╛рд░реНрд╕рд░ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдЧрд╛ рдЬреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред рдПрдПрд╕рдЯреА рдореЗрдВ рдиреЛрдбреНрд╕ рд╣реЛрддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдиреЛрдб рдПрдХ рдирд┐рдпрдорд┐рдд рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ type
рд╕рдВрдкрддреНрддрд┐ рд╣реЛрддреА рд╣реИ рдЬреЛ рдиреЛрдб рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреА рд╣реИ, рд╕рд╛рде рд╣реА рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдЬреЛ рдХрд┐ рдкреНрд░рдХрд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред
рдЯрд╛рдЗрдк | рд╕рдВрд░рдЪрдирд╛ |
---|
рд╕рдВрдЦреНрдпрд╛ | { type: "num", value: NUMBER } |
str | { type: "str", value: STRING } |
bool | { type: "bool", value: true or false } |
рд╡рд░ | { type: "var", value: NAME } |
рд▓реИрдореНрдмреНрдбрд╛ | { type: "lambda", vars: [ NAME... ], body: AST } |
рдХреЙрд▓ | { type: "call", func: AST, args: [ AST... ] } |
рдЕрдЧрд░ | { type: "if", cond: AST, then: AST, else: AST } |
рдЕрд╕рд╛рдЗрди | { type: "assign", operator: "=", left: AST, right: AST } |
рдмрд╛рдЗрдирд░реА | { type: "binary", operator: OPERATOR, left: AST, right: AST } |
рдареЗрд▓рд╛ | { type: "prog", prog: [ AST... ] } |
рдЪрд▓реЛ | { type: "let", vars: [ VARS... ], body: AST } |
рдЙрджрд╛рд╣рд░рдгрд╕рдВрдЦреНрдпрд╛ ( num
):
123.5
{ type: "num", value: 123.5 }
рд▓рд╛рдЗрдиреЗрдВ ( str
):
"Hello World"
{ type: "str", value: "Hello World!" }
true
рдФрд░ false
( bool
):
true false
{ type: "bool", value: true } { type: "bool", value: false }
рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ ( var
):
foo
{ type: "var", value: "foo" }
рдХрд╛рд░реНрдп ( lambda
):
lambda (x) 10
{ type: "lambda", vars: [ "x" ], body: { type: "num", value: 10 } }
рдмрд╛рдж рдореЗрдВ рд╣рдо рдПрдХ рдирд╛рдо рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ name
рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЙрдирдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ ( call
):
foo(a, 1)
{ "type": "call", "func": { "type": "var", "value": "foo" }, "args": [ { "type": "var", "value": "a" }, { "type": "num", "value": 1 } ] }
рд╢рд╛рдЦрд╛рдПрдБ ( if
):
if foo then bar else baz
{ "type": "if", "cond": { "type": "var", "value": "foo" }, "then": { "type": "var", "value": "bar" }, "else": { "type": "var", "value": "baz" } }
else
рдмрд┐рдирд╛:
if foo then bar
{ "type": "if", "cond": { "type": "var", "value": "foo" }, "then": { "type": "var", "value": "bar" } }
рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ ( assign
):
a = 10
{ "type": "assign", "operator": "=", "left": { "type": "var", "value": "a" }, "right": { "type": "num", "value": 10 } }
рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрдЯрд░ ( binary
):
x + y * z
{ "type": "binary", "operator": "+", "left": { "type": "var", "value": "x" }, "right": { "type": "binary", "operator": "*", "left": { "type": "var", "value": "y" }, "right": { "type": "var", "value": "z" } } }
рдЕрдиреБрдХреНрд░рдо ( prog
):
{ a = 5; b = a * 2; a + b; }
{ "type": "prog", "prog": [ { "type": "assign", "operator": "=", "left": { "type": "var", "value": "a" }, "right": { "type": "num", "value": 5 } }, { "type": "assign", "operator": "=", "left": { "type": "var", "value": "b" }, "right": { "type": "binary", "operator": "*", "left": { "type": "var", "value": "a" }, "right": { "type": "num", "value": 2 } } }, { "type": "binary", "operator": "+", "left": { "type": "var", "value": "a" }, "right": { "type": "var", "value": "b" } } ] }
рдмреНрд▓реЙрдХ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдЪрд░ ( let
):
let (a = 10, b = a * 10) { a + b; }
{ "type": "let", "vars": [ { "name": "a", "def": { "type": "num", "value": 10 } }, { "name": "b", "def": { "type": "binary", "operator": "*", "left": { "type": "var", "value": "a" }, "right": { "type": "num", "value": 10 } } } ], "body": { "type": "binary", "operator": "+", "left": { "type": "var", "value": "a" }, "right": { "type": "var", "value": "b" } } }
рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдб рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рд╣рдо рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред
рдкрд╛рд░реНрд╕рд░
рдкрд╛рд░реНрд╕рд░ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдкреЗрдбрд╝ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдЧрд╛ред
рдЙрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдЬреЛ рд╣рдордиреЗ рдЯреЛрдХрди рдореЗрдВ рдХрд┐рдпрд╛ рдерд╛, рдкрд╛рд░реНрд╕рд░ рдкрд╛рддреНрд░реЛрдВ рдХреА рдПрдХ рдзрд╛рд░рд╛ рдХреЗ рдмрдЬрд╛рдп рдЯреЛрдХрди рдХреА рдПрдХ рдзрд╛рд░рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднреА рднреА рдХрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВред рд╣рдо рдореБрдЦреНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред рдЪрд▓реЛ рдПрдХ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп, рдкрд╛рд░реНрд╕рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
function parse_lambda() { return { type: "lambda", vars: delimited("(", ")", ",", parse_varname), body: parse_expression() }; }
рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рддрдм рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм lambda
рдХреАрд╡рд░реНрдб рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЯреЛрдХрди рд╕реНрдЯреНрд░реАрдо рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХреЗрд╡рд▓ рддрд░реНрдХреЛрдВ рдХреЗ рдирд╛рдо рд▓реЗрдиреЗ рд╣реЛрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рд╡реЗ рдХреЛрд╖реНрдардХ рдореЗрдВ рд╣реИрдВ рдФрд░ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рд╣рдо рдЗрд╕реЗ delimited
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдирд┐рдореНрди рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ: start
, stop
, separator
, parser
рдлрд╝рдВрдХреНрд╢рди, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо parse_varname
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛ рдлреЗрдВрдХрддрд╛ рд╣реИ рдпрджрд┐ рдпрд╣ рдХреБрдЫ рдРрд╕рд╛ рдиреЛрдЯрд┐рд╕ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЪрд░ рдХреА рддрд░рд╣ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИред рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╢рд░реАрд░ рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ parse_expression
рд╕рд╛рде рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
delimited
рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрди рд╕реНрддрд░ рд╣реИ:
function delimited(start, stop, separator, parser) { var a = [], first = true; skip_punc(start); while (!input.eof()) { if (is_punc(stop)) break; if (first) first = false; else skip_punc(separator); if (is_punc(stop)) break;
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдФрд░ рднреА рдЕрдзрд┐рдХ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: is_punc
рдФрд░ skip_punc
ред рдкрд╣рд▓рд╛ рд░рд┐рдЯрд░реНрди true
рдЕрдЧрд░ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрди рд╣реИ (рдЗрд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдмрд┐рдирд╛), рдЬрдмрдХрд┐ skip_punc
рдпрд╣ рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрди рд╡рд░реНрдг рд╣реИ рдФрд░ рдЗрд╕реЗ рдирд┐рдХрд╛рд▓реЗрдВ (рдпрд╛ рдЕрдиреНрдпрдерд╛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХреЗрдВ)ред
рдкреВрд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХрд╛рд░реНрдп рд╕рдмрд╕реЗ рд╕рд░рд▓ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ:
function parse_toplevel() { var prog = []; while (!input.eof()) { prog.push(parse_expression()); if (!input.eof()) skip_punc(";"); } return { type: "prog", prog: prog }; }
рдЪреВрдБрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ рднрд╛рд╡ рд╣реИрдВ, рд╣рдо рдмрд╕ parse_expression()
рдХрд╣рддреЗ рд╣реИрдВ рдФрд░ рднрд╛рд╡реЛрдВ рдХреЛ рддрдм рддрдХ рдкрдврд╝рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рд╣рдо рд╕рдм рдХреБрдЫ рдирд╣реАрдВ рдкрдврд╝ рд▓реЗрддреЗред skip_punc(";")
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдХрд░рддреЗ рд╣реИрдВ ;
рдкреНрд░рддреНрдпреЗрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрд╛рдж рдЕрдирд┐рд╡рд╛рд░реНрдп рд╣реИред
рдПрдХ рдФрд░ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ parse_if()
:
function parse_if() { skip_kw("if"); var cond = parse_expression(); if (!is_punc("{")) skip_kw("then"); var then = parse_expression(); var ret = { type: "if", cond: cond, then: then }; if (is_kw("else")) { input.next(); ret.else = parse_expression(); } return ret; }
if
рд╡рд╣ рдХреАрд╡рд░реНрдб рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ (рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди if
рдХреАрд╡рд░реНрдб рдирд╣реАрдВ рд╣реИ, if
рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрддрд╛ рд╣реИ), if
parse_expression()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдерд┐рддрд┐ рдкрдврд╝рддрд╛ рд╣реИред рдпрджрд┐ рдкреНрд░рддреАрдХ {
рдЖрдЧреЗ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рддрдм рдХреАрд╡рд░реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ)ред рд╢рд╛рдЦрд╛рдПрдБ рд╕рд┐рд░реНрдл рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрдирдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ parse_expression()
рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред else
рд╢рд╛рдЦрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХреАрд╡рд░реНрдб рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред
рдХрдИ рдЫреЛрдЯреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде, рд╣рдо рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдордиреЗ рдкрд╛рд░реНрд╕рд░ рдХреЛ рд▓рдЧрднрдЧ рд╡реИрд╕рд╛ рд╣реА рд▓рд┐рдЦрд╛ рд╣реИ, рдЕрдЧрд░ рд╣рдо рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдЪреНрдЪ рд╕реНрддрд░реАрдп рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпреЗ рд╕рднреА рдлрд╝рдВрдХреНрд╢рди "рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ рдкреБрдирд░рд╛рд╡рд░реНрддреА" рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ parse_atom()
, рдЬреЛ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ parse_if()
(рдЬрд┐рд╕реЗ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рд╣реИ if
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдФрд░ рдпрд╣ рдмрджрд▓реЗ рдореЗрдВ parse_expression()
рдХрд╣рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди parse_expression()
рдХрд╣рддрд╛ рд╣реИред рдХреЛрдИ рдЕрдирдВрдд рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣рдореЗрд╢рд╛ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЯреЛрдХрди рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИред
рдЗрд╕ рддрд░рд╣ рдХреА рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╡рд┐рдзрд┐ рдХреЛ рд░рд┐рдХрд░реНрд╕рд┐рд╡ рдбрд┐рд╕реЗрдВрдЯ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд▓рд┐рдЦрдирд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╣реИред
рдирд┐рдЪрд▓рд╛ рд╕реНрддрд░: parse_atom()
рдФрд░ parse_expression()
parse_atom()
рдлрд╝рдВрдХреНрд╢рди рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ:
function parse_atom() { return maybe_call(function(){ if (is_punc("(")) { input.next(); var exp = parse_expression(); skip_punc(")"); return exp; } if (is_punc("{")) return parse_prog(); if (is_kw("if")) return parse_if(); if (is_kw("true") || is_kw("false")) return parse_bool(); if (is_kw("lambda") || is_kw("╬╗")) { input.next(); return parse_lambda(); } var tok = input.next(); if (tok.type == "var" || tok.type == "num" || tok.type == "str") return tok; unexpected(); }); }
рдЬрдм рд╡рд╣ рд╢реБрд░реБрдЖрддреА рдмреНрд░реИрдХреЗрдЯ рдХреЛ рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рдХреЛрд╖реНрдардХ рдХреА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП, рдмреНрд░реИрдХреЗрдЯ рдХреЛ рдЫреЛрдбрд╝рддреЗ рд╣реБрдП, рдлрд╝рдВрдХреНрд╢рди parse_expression()
рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╕рдорд╛рдкрди рдмреНрд░реИрдХреЗрдЯ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рд╡рд╣ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХреАрд╡рд░реНрдб рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рд╕рдВрдмрдВрдзрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рд╡рд╣ рдПрдХ рд╕реНрдерд┐рд░ рдпрд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рджреЗрдЦрддреА рд╣реИ, рддреЛ рдЙрд╕реЗ рдЙрд╕реА рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рддреА рд╣реИред рдФрд░ рдЕрдЧрд░ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ, рддреЛ рдпрд╣ unexpected()
рдХрд╣рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИред
рдЬрдм рд╡рд╣ {
рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рд╡рд╣ parse_prog
рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП parse_prog
рдХрд╣рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, parse_prog
рдПрдХ рд╕рд░рд▓ рдЕрдиреБрдХреВрд▓рди рдХрд░рддрд╛ рд╣реИ: рдпрджрд┐ {
рдФрд░ }
рдмреАрдЪ рдХреЛрдИ рднрд╛рд╡ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдпрд╣ false
, рдпрджрд┐ рдХреЗрд╡рд▓ рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИ, рддреЛ рдпрд╣ рдХреЗрд╡рд▓ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред рдЕрдиреНрдпрдерд╛, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЗ рд╕рд╛рде prog
рдиреЛрдб рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рд╣реИред
рдФрд░ рдпрд╣рд╛рдБ parse_expression()
рдлрд╝рдВрдХреНрд╢рди рд╣реИред parse_atom()
рд╡рд┐рдкрд░реАрдд, рдпрд╣ рд╕рдВрднрд╡ рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ рднрд╛рд╡реЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдЧрд╛ред
function parse_expression() { return maybe_call(function(){ return maybe_binary(parse_atom(), 0); }); }
рдХрд╛рд░реНрдп maybe_*
рдпреЗ рдлрд╝рдВрдХреНрд╢рди рдпрд╣ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрд╛рдж рдХреНрдпрд╛ рдЖрддрд╛ рд╣реИ рдФрд░ рдпрд╣ рддрдп рдХрд░рдирд╛ рд╣реИ рдХрд┐ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЙрд╕рдХреЗ рдиреЛрдб рдореЗрдВ рд▓рдкреЗрдЯрдирд╛ рд╣реИ, рдпрд╛ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╣реИред
maybe_call()
рдлрд╝рдВрдХреНрд╢рди рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ: рдпрд╣ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдпрд╣ рд╕рд╛рдордирд╛ рдХрд░рддрд╛ рд╣реИ (
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрд╛рдж, рдпрд╣ call
рдореЗрдВ рдЦреБрдж рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХреИрд╕реЗ delimited()
рддрд░реНрдХреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИ:
function maybe_call(expr) { expr = expr(); return is_punc("(") ? parse_call(expr) : expr; } function parse_call(func) { return { type: "call", func: func, args: delimited("(", ")", ",", parse_expression) }; }
рд╕рдВрдЪрд╛рд▓рдХ рдкреНрд░рд╛рдердорд┐рдХрддрд╛
maybe_binary(left, my_prec)
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ 1 + 2 * 3
рдЬреИрд╕реЗ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓рдмреНрдмреЛрд▓реБрдЖрдм рдпрд╣ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
var PRECEDENCE = { "=": 1, "||": 2, "&&": 3, "<": 7, ">": 7, "<=": 7, ">=": 7, "==": 7, "!=": 7, "+": 10, "-": 10, "*": 20, "/": 20, "%": 20, };
, *
"", +
, , 1 + 2 * 3
(1 + (2 * 3))
((1 + 2) * 3)
.
, ( read_atom
) maybe_binary()
( ), ( my_prec
). maybe_binary
, . , , .
, , , binary
, , , (*):
function maybe_binary(left, my_prec) { var tok = is_op(); if (tok) { var his_prec = PRECEDENCE[tok.value]; if (his_prec > my_prec) { input.next(); var right = maybe_binary(parse_atom(), his_prec)
, , , maybe_binary
, ( my_prec
), , , . - , (, ), .
, , my_prec
0, binary
( assign
=
).
, .
var FALSE = { type: "bool", value: false }; function parse(input) { var PRECEDENCE = { "=": 1, "||": 2, "&&": 3, "<": 7, ">": 7, "<=": 7, ">=": 7, "==": 7, "!=": 7, "+": 10, "-": 10, "*": 20, "/": 20, "%": 20, }; return parse_toplevel(); function is_punc(ch) { var tok = input.peek(); return tok && tok.type == "punc" && (!ch || tok.value == ch) && tok; } function is_kw(kw) { var tok = input.peek(); return tok && tok.type == "kw" && (!kw || tok.value == kw) && tok; } function is_op(op) { var tok = input.peek(); return tok && tok.type == "op" && (!op || tok.value == op) && tok; } function skip_punc(ch) { if (is_punc(ch)) input.next(); else input.croak("Expecting punctuation: \"" + ch + "\""); } function skip_kw(kw) { if (is_kw(kw)) input.next(); else input.croak("Expecting keyword: \"" + kw + "\""); } function skip_op(op) { if (is_op(op)) input.next(); else input.croak("Expecting operator: \"" + op + "\""); } function unexpected() { input.croak("Unexpected token: " + JSON.stringify(input.peek())); } function maybe_binary(left, my_prec) { var tok = is_op(); if (tok) { var his_prec = PRECEDENCE[tok.value]; if (his_prec > my_prec) { input.next(); return maybe_binary({ type : tok.value == "=" ? "assign" : "binary", operator : tok.value, left : left, right : maybe_binary(parse_atom(), his_prec) }, my_prec); } } return left; } function delimited(start, stop, separator, parser) { var a = [], first = true; skip_punc(start); while (!input.eof()) { if (is_punc(stop)) break; if (first) first = false; else skip_punc(separator); if (is_punc(stop)) break; a.push(parser()); } skip_punc(stop); return a; } function parse_call(func) { return { type: "call", func: func, args: delimited("(", ")", ",", parse_expression), }; } function parse_varname() { var name = input.next(); if (name.type != "var") input.croak("Expecting variable name"); return name.value; } function parse_if() { skip_kw("if"); var cond = parse_expression(); if (!is_punc("{")) skip_kw("then"); var then = parse_expression(); var ret = { type: "if", cond: cond, then: then, }; if (is_kw("else")) { input.next(); ret.else = parse_expression(); } return ret; } function parse_lambda() { return { type: "lambda", vars: delimited("(", ")", ",", parse_varname), body: parse_expression() }; } function parse_bool() { return { type : "bool", value : input.next().value == "true" }; } function maybe_call(expr) { expr = expr(); return is_punc("(") ? parse_call(expr) : expr; } function parse_atom() { return maybe_call(function(){ if (is_punc("(")) { input.next(); var exp = parse_expression(); skip_punc(")"); return exp; } if (is_punc("{")) return parse_prog(); if (is_kw("if")) return parse_if(); if (is_kw("true") || is_kw("false")) return parse_bool(); if (is_kw("lambda") || is_kw("╬╗")) { input.next(); return parse_lambda(); } var tok = input.next(); if (tok.type == "var" || tok.type == "num" || tok.type == "str") return tok; unexpected(); }); } function parse_toplevel() { var prog = []; while (!input.eof()) { prog.push(parse_expression()); if (!input.eof()) skip_punc(";"); } return { type: "prog", prog: prog }; } function parse_prog() { var prog = delimited("{", "}", ";", parse_expression); if (prog.length == 0) return FALSE; if (prog.length == 1) return prog[0]; return { type: "prog", prog: prog }; } function parse_expression() { return maybe_call(function(){ return maybe_binary(parse_atom(), 0); }); } }
Marijn Haverbeke, parse-js (Common Lisp), , . , , JS, .
: JavaScript. рднрд╛рдЧ 2: рджреБрднрд╛рд╖рд┐рдпрд╛