
import STDLIB/default-instruction-set.lm;
import STDLIB/default-primitives.lm;
import STDLIB/default-rules.lm;
import STDLIB/default-stdlib.lm;

import STRICT/ast.lm;
import STRICT/utility.lm;
import STRICT/tokenize.lm;
import STRICT/parse.lm;
import STRICT/preprocess.lm;
import STRICT/typecheck.lm;
import STRICT/expression.lm;
import STRICT/codegen.lm;
import STRICT/fragment.lm;
import STRICT/assemble.lm;

config-strict                := True_u8;
config-preprocess            := True_u8;
config-target                := 'tmp.s_s;

type CompileMode ModeTokenize | ModeParse | ModePreprocess | ModeTypecheck | ModeCompile;
config-mode                  := (: ModeCompile CompileMode);

main := λ(: argc U64)(: argv String[]).(tail(
   (let argi 1_u64)
   (let input SNil)
   ()
   (while (<( argi argc )) (
      (match ([]( argv argi )) (
         ()
         ('--tokenize_s (set config-mode ModeTokenize))
         ('--parse_s (set config-mode ModeParse))
         ('--preprocess_s (set config-mode ModePreprocess))
         ('--typecheck_s (set config-mode ModeTypecheck))
         ('--compile_s (set config-mode ModeCompile))
         ('--strict_s (set config-strict True_u8))
         ('--gradual_s (set config-strict False_u8))
         ('--macro_s (set config-preprocess True_u8))
         ('--nomacro_s (set config-preprocess False_u8))
         ('-o_s (tail(
            (set argi (+( argi 1_u64 )))
            (set config-target ([]( argv argi )))
         )))
         (fp (
            (set input (SCons(
               (close input)
               (close (SAtom( fp )))
            )))
         ))
      ))
      (set argi (+( argi 1_u64 )))
   ))

   (let continue True_u8)
   (while (==( continue True_u8 )) (match input (
      ()
      ( SNil (set continue False_u8) )
      ( (SCons( rst SNil )) (set input rst) )
      ( (SCons( rst (SAtom( fp )) )) (tail( (tokenize fp) (set input rst) )))
      ( (SAtom( fp )) (tail( (tokenize fp) (set continue False_u8) )))
   )))

   (match config-mode (
      ()
      ( ModeTokenize () )
      ( ModeParse (parse()) )
      ( ModePreprocess (tail(
         (parse())
         (preprocess())
      )))
      ( ModeTypecheck (tail(
         (parse())
         (preprocess())
         (typecheck())
      )))
      ( ModeCompile (tail(
         (parse())
         (preprocess())
         (typecheck())
         (compile())
      )))
   ))

));

