2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  All  rights  reserved . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Redistribution  and  use  in  source  and  binary  forms ,  with  or  without 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  modification ,  are  permitted  provided  that  the  following  conditions  are  met : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  1.  Redistributions  of  source  code  must  retain  the  above  copyright  notice ,  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     list  of  conditions  and  the  following  disclaimer . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  2.  Redistributions  in  binary  form  must  reproduce  the  above  copyright  notice , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     this  list  of  conditions  and  the  following  disclaimer  in  the  documentation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *     and / or  other  materials  provided  with  the  distribution . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  THIS  SOFTWARE  IS  PROVIDED  BY  THE  COPYRIGHT  HOLDERS  AND  CONTRIBUTORS  " AS IS " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES ,  INCLUDING ,  BUT  NOT  LIMITED  TO ,  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  IMPLIED  WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR  PURPOSE  ARE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  DISCLAIMED .  IN  NO  EVENT  SHALL  THE  COPYRIGHT  HOLDER  OR  CONTRIBUTORS  BE  LIABLE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  FOR  ANY  DIRECT ,  INDIRECT ,  INCIDENTAL ,  SPECIAL ,  EXEMPLARY ,  OR  CONSEQUENTIAL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  DAMAGES  ( INCLUDING ,  BUT  NOT  LIMITED  TO ,  PROCUREMENT  OF  SUBSTITUTE  GOODS  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SERVICES ;  LOSS  OF  USE ,  DATA ,  OR  PROFITS ;  OR  BUSINESS  INTERRUPTION )  HOWEVER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY ,  WHETHER  IN  CONTRACT ,  STRICT  LIABILITY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OR  TORT  ( INCLUDING  NEGLIGENCE  OR  OTHERWISE )  ARISING  IN  ANY  WAY  OUT  OF  THE  USE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  OF  THIS  SOFTWARE ,  EVEN  IF  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 10:51:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ByteBuffer.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <AK/NonnullOwnPtr.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-12 10:51:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/ArgsParser.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibCore/File.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/AST.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Interpreter.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-11 19:27:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Parser.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Array.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Date.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-02 09:54:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Error.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-26 14:54:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Function.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:53:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/GlobalObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-16 14:20:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Object.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/PrimitiveString.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-04-02 19:32:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Shape.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-16 14:20:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibJS/Runtime/Value.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:34:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibLine/Editor.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <stdio.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 11:52:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Vector < String >  repl_statements ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  ReplObject  :  public  JS : : GlobalObject  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ReplObject ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    virtual  ~ ReplObject ( )  override ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    virtual  const  char *  class_name ( )  const  override  {  return  " ReplObject " ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  JS : : Value  exit_interpreter ( JS : : Interpreter & ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  JS : : Value  repl_help ( JS : : Interpreter & ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  JS : : Value  load_file ( JS : : Interpreter & ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 11:52:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  JS : : Value  save_to_file ( JS : : Interpreter & ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  dump_ast  =  false ;  
						 
					
						
							
								
									
										
										
										
											2020-03-31 19:00:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  OwnPtr < Line : : Editor >  editor ;  
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  read_next_piece ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  piece ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  level  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 22:44:23 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringBuilder  prompt_builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 22:44:23 +04:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        prompt_builder . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prompt_builder . append ( " >  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto  i  =  0 ;  i  <  level ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            prompt_builder . append ( "      " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 19:00:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        String  line  =  editor - > get_line ( prompt_builder . build ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        piece . append ( line ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  lexer  =  JS : : Lexer ( line ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( JS : : Token  token  =  lexer . next ( ) ;  token . type ( )  ! =  JS : : TokenType : : Eof ;  token  =  lexer . next ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            switch  ( token . type ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  JS : : TokenType : : BracketOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  JS : : TokenType : : CurlyOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  JS : : TokenType : : ParenOpen : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                level + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  JS : : TokenType : : BracketClose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  JS : : TokenType : : CurlyClose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            case  JS : : TokenType : : ParenClose : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                level - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  while  ( level  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  piece . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  print_value ( JS : : Value  value ,  HashTable < JS : : Object * > &  seen_objects ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  print_array ( const  JS : : Array &  array ,  HashTable < JS : : Object * > &  seen_objects )  
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fputs ( " [  " ,  stdout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  array . elements ( ) . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print_value ( array . elements ( ) [ i ] ,  seen_objects ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( i  ! =  array . elements ( ) . size ( )  -  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fputs ( " ,  " ,  stdout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fputs ( "  ] " ,  stdout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  print_object ( const  JS : : Object &  object ,  HashTable < JS : : Object * > &  seen_objects )  
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fputs ( " {  " ,  stdout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  index  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 19:32:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  it  :  object . shape ( ) . property_table ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        printf ( " \" \033 [33;1m%s \033 [0m \" :  " ,  it . key . characters ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 19:32:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        print_value ( object . get_direct ( it . value . offset ) ,  seen_objects ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( index  ! =  object . shape ( ) . property_table ( ) . size ( )  -  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            fputs ( " ,  " ,  stdout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + + index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fputs ( "  } " ,  stdout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  print_function ( const  JS : : Object &  function ,  HashTable < JS : : Object * > & )  
						 
					
						
							
								
									
										
										
										
											2020-03-26 14:54:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    printf ( " \033 [34;1m[%s] \033 [0m " ,  function . class_name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 14:54:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  print_date ( const  JS : : Object &  date ,  HashTable < JS : : Object * > & )  
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    printf ( " \033 [34;1mDate %s \033 [0m " ,  static_cast < const  JS : : Date & > ( date ) . string ( ) . characters ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 09:54:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  print_error ( const  JS : : Object &  object ,  HashTable < JS : : Object * > & )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  error  =  static_cast < const  JS : : Error & > ( object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 14:18:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    printf ( " \033 [34;1m[%s] \033 [0m " ,  error . name ( ) . characters ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! error . message ( ) . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        printf ( " : %s " ,  error . message ( ) . characters ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 09:54:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  print_value ( JS : : Value  value ,  HashTable < JS : : Object * > &  seen_objects )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_object ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( seen_objects . contains ( & value . as_object ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // FIXME: Maybe we should only do this for circular references,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //        not for all reoccurring objects.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            printf ( " <already printed Object %p> " ,  & value . as_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        seen_objects . set ( & value . as_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_array ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  print_array ( static_cast < const  JS : : Array & > ( value . as_object ( ) ) ,  seen_objects ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 18:53:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( value . is_object ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  object  =  value . as_object ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( object . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  print_function ( object ,  seen_objects ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:18:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( object . is_date ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  print_date ( object ,  seen_objects ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 09:54:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( object . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  print_error ( object ,  seen_objects ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 18:43:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  print_object ( object ,  seen_objects ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        printf ( " \033 [31;1m " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( value . is_number ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        printf ( " \033 [35;1m " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( value . is_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        printf ( " \033 [32;1m " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 14:54:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( value . is_null ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        printf ( " \033 [33;1m " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( value . is_undefined ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:26:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        printf ( " \033 [34;1m " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        putchar ( ' " ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    printf ( " %s " ,  value . to_string ( ) . characters ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( value . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        putchar ( ' " ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    printf ( " \033 [0m " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  print ( JS : : Value  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashTable < JS : : Object * >  seen_objects ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print_value ( value ,  seen_objects ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    putchar ( ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  file_has_shebang ( AK : : ByteBuffer  file_contents )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( file_contents . size ( )  > =  2  & &  file_contents [ 0 ]  = =  ' # '  & &  file_contents [ 1 ]  = =  ' ! ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								StringView  strip_shebang ( AK : : ByteBuffer  file_contents )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( i  =  2 ;  i  <  file_contents . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( file_contents [ i ]  = =  ' \n ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  StringView ( ( const  char * ) file_contents . data ( )  +  i ,  file_contents . size ( )  -  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 11:52:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  write_to_file ( const  StringView &  path )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  fd  =  open_with_path_length ( path . characters_without_null_termination ( ) ,  path . length ( ) ,  O_WRONLY  |  O_CREAT  |  O_TRUNC ,  0666 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  repl_statements . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  line  =  repl_statements [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( line . length ( )  & &  i  ! =  repl_statements . size ( )  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ssize_t  nwritten  =  write ( fd ,  line . characters ( ) ,  line . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( nwritten  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                close ( fd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( i  ! =  repl_statements . size ( )  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            char  ch  =  ' \n ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ssize_t  nwritten  =  write ( fd ,  & ch ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( nwritten  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                perror ( " write " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                close ( fd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    close ( fd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ReplObject : : ReplObject ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    put_native_function ( " exit " ,  exit_interpreter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    put_native_function ( " help " ,  repl_help ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 14:13:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    put_native_function ( " load " ,  load_file ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    put_native_function ( " save " ,  save_to_file ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ReplObject : : ~ ReplObject ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-02 11:52:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								JS : : Value  ReplObject : : save_to_file ( JS : : Interpreter &  interpreter )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! interpreter . argument_count ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  JS : : Value ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    String  save_path  =  interpreter . argument ( 0 ) . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringView  path  =  StringView ( save_path . characters ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( write_to_file ( path ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  JS : : Value ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  JS : : Value ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								JS : : Value  ReplObject : : exit_interpreter ( JS : : Interpreter &  interpreter )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! interpreter . argument_count ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        exit ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  exit_code  =  interpreter . argument ( 0 ) . to_number ( ) . as_double ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    exit ( exit_code ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  JS : : js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								JS : : Value  ReplObject : : repl_help ( JS : : Interpreter &  interpreter )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  help_text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    help_text . append ( " REPL commands: \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    help_text . append ( "     exit(code): exit the REPL with specified code. Defaults to 0. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    help_text . append ( "     help(): display this menu \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    help_text . append ( "     load(files): Accepts file names as params to load into running session. For example repl.load( \" js/1.js \" ,  \" js/2.js \" ,  \" js/3.js \" ) \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    String  result  =  help_text . to_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-04 12:57:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  js_string ( interpreter ,  result ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								JS : : Value  ReplObject : : load_file ( JS : : Interpreter &  interpreter )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! interpreter . argument_count ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  JS : : Value ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 22:38:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  file  :  interpreter . call_frame ( ) . arguments )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        String  file_name  =  file . as_string ( ) - > string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  js_file  =  Core : : File : : construct ( file_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! js_file - > open ( Core : : IODevice : : ReadOnly ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fprintf ( stderr ,  " Failed to open %s: %s \n " ,  file_name . characters ( ) ,  js_file - > error_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  file_contents  =  js_file - > read_all ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        StringView  source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( file_has_shebang ( file_contents ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            source  =  strip_shebang ( file_contents ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            source  =  file_contents ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  program  =  JS : : Parser ( JS : : Lexer ( source ) ) . parse_program ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( dump_ast ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            program - > dump ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  result  =  interpreter . run ( * program ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  JS : : Value ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  repl ( JS : : Interpreter &  interpreter )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        String  piece  =  read_next_piece ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( piece . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 13:29:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 11:52:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        repl_statements . append ( piece ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  program  =  JS : : Parser ( JS : : Lexer ( piece ) ) . parse_program ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( dump_ast ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            program - > dump ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  result  =  interpreter . run ( * program ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 09:54:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter . exception ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 15:25:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            printf ( " Uncaught exception:  " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 09:54:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            print ( interpreter . exception ( ) - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter . clear_exception ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-09 21:58:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 10:51:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  main ( int  argc ,  char * *  argv )  
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-03-16 19:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  gc_on_every_allocation  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-20 14:52:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  print_last_result  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 10:51:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  char *  script_path  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Core : : ArgsParser  args_parser ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 10:03:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    args_parser . add_option ( dump_ast ,  " Dump the AST " ,  " dump-ast " ,  ' A ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-24 14:45:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    args_parser . add_option ( print_last_result ,  " Print last result " ,  " print-last-result " ,  ' l ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-16 19:18:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    args_parser . add_option ( gc_on_every_allocation ,  " GC on every allocation " ,  " gc-on-every-allocation " ,  ' g ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    args_parser . add_positional_argument ( script_path ,  " Path to script file " ,  " script " ,  Core : : ArgsParser : : Required : : No ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 10:51:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    args_parser . parse ( argc ,  argv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( script_path  = =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  interpreter  =  JS : : Interpreter : : create < ReplObject > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter - > heap ( ) . set_should_collect_on_every_allocation ( gc_on_every_allocation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter - > global_object ( ) . put ( " global " ,  & interpreter - > global_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 19:00:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        editor  =  make < Line : : Editor > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        editor - > initialize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 21:04:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        repl ( * interpreter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  interpreter  =  JS : : Interpreter : : create < JS : : GlobalObject > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter - > heap ( ) . set_should_collect_on_every_allocation ( gc_on_every_allocation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        interpreter - > global_object ( ) . put ( " global " ,  & interpreter - > global_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  file  =  Core : : File : : construct ( script_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! file - > open ( Core : : IODevice : : ReadOnly ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fprintf ( stderr ,  " Failed to open %s: %s \n " ,  script_path ,  file - > error_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  file_contents  =  file - > read_all ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        StringView  source ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 15:20:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( file_has_shebang ( file_contents ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            source  =  strip_shebang ( file_contents ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            source  =  file_contents ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  program  =  JS : : Parser ( JS : : Lexer ( source ) ) . parse_program ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-12 10:51:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( dump_ast ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            program - > dump ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-01 21:04:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  result  =  interpreter - > run ( * program ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 10:55:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( interpreter - > exception ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            printf ( " Uncaught exception:  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( interpreter - > exception ( ) - > value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            interpreter - > clear_exception ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 21:52:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 10:55:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 21:52:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( print_last_result ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            print ( result ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 01:10:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-08 19:59:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 19:42:11 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}