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