@@ -789,6 +789,64 @@ pub unsafe fn compile_statement(l: *mut Lexer, c: *mut Compiler) -> Option<()> {
789789 push_opcode ( Op :: Label { label : out_label} , ( * l) . loc , c) ;
790790 Some ( ( ) )
791791 }
792+ Token :: For => {
793+ scope_push ( & mut ( * c) . vars ) ;
794+ get_and_expect_token ( l, Token :: OParen ) ?;
795+
796+ let cond_label = allocate_label_index ( c) ;
797+ let iter_label = allocate_label_index ( c) ;
798+ let body_label = allocate_label_index ( c) ;
799+ let out_label = allocate_label_index ( c) ;
800+
801+ let saved_point = ( * l) . parse_point ;
802+ lexer:: get_token ( l) ?;
803+
804+ if ( * l) . token == Token :: Auto {
805+ get_and_expect_token ( l, Token :: ID ) ?;
806+ let name = arena:: strdup ( & mut ( * c) . arena , ( * l) . string ) ;
807+ let index = allocate_auto_var ( & mut ( * c) . auto_vars_ator ) ;
808+ declare_var ( c, name, ( * l) . loc , Storage :: Auto { index} ) ?;
809+ get_and_expect_token ( l, Token :: Eq ) ?;
810+ let loc = ( * l) . loc ;
811+ let ( arg, _) = compile_expression ( l, c) ?;
812+ push_opcode ( Op :: AutoAssign { index, arg} , loc, c) ;
813+ get_and_expect_token ( l, Token :: SemiColon ) ?;
814+ } else if ( * l) . token != Token :: SemiColon {
815+ ( * l) . parse_point = saved_point;
816+ compile_expression ( l, c) ?;
817+ get_and_expect_token ( l, Token :: SemiColon ) ?;
818+ }
819+
820+ push_opcode ( Op :: Label { label : cond_label} , ( * l) . loc , c) ;
821+ let saved_point = ( * l) . parse_point ;
822+ lexer:: get_token ( l) ;
823+ if ( * l) . token != Token :: SemiColon {
824+ ( * l) . parse_point = saved_point;
825+ let ( arg, _) = compile_expression ( l, c) ?;
826+ push_opcode ( Op :: JmpIfNotLabel { label : out_label, arg} , ( * l) . loc , c) ;
827+ get_and_expect_token ( l, Token :: SemiColon ) ?;
828+ }
829+ push_opcode ( Op :: JmpLabel { label : body_label} , ( * l) . loc , c) ;
830+
831+ push_opcode ( Op :: Label { label : iter_label} , ( * l) . loc , c) ;
832+ let saved_point = ( * l) . parse_point ;
833+ lexer:: get_token ( l) ;
834+ if ( * l) . token != Token :: CParen {
835+ ( * l) . parse_point = saved_point;
836+ compile_expression ( l, c) ?;
837+ get_and_expect_token ( l, Token :: CParen ) ?;
838+ }
839+ push_opcode ( Op :: JmpLabel { label : cond_label} , ( * l) . loc , c) ;
840+
841+
842+ push_opcode ( Op :: Label { label : body_label} , ( * l) . loc , c) ;
843+ compile_statement ( l, c) ?;
844+ push_opcode ( Op :: JmpLabel { label : iter_label} , ( * l) . loc , c) ;
845+ push_opcode ( Op :: Label { label : out_label} , ( * l) . loc , c) ;
846+
847+ scope_pop ( & mut ( * c) . vars ) ;
848+ Some ( ( ) )
849+ }
792850 Token :: Return => {
793851 get_and_expect_tokens ( l, & [ Token :: SemiColon , Token :: OParen ] ) ?;
794852 if ( * l) . token == Token :: SemiColon {
0 commit comments