
# Dependencies

import STDLIB/default-cons-allocator.lm;
import STDLIB/default-atom-allocator.lm;

import PRODUCTION/utility.lm;
import PRODUCTION/context.lm;
import PRODUCTION/tokenize.lm;
import PRODUCTION/parse.lm;
import PRODUCTION/preprocess.lm;
import PRODUCTION/typecheck.lm;
import PRODUCTION/expression.lm;
import PRODUCTION/codegen-dynamic.lm;
import PRODUCTION/codegen-strict.lm;
import PRODUCTION/stack.lm;
import PRODUCTION/fragment.lm;
import PRODUCTION/assemble.lm;
import PRODUCTION/data.lm;

# Static Globals

config-perf                              := ();
config-debug                             := ();
config-nomacro                           := ();
config-nostd                             := ();
config-strict                            := ();
cli-config                               := ();

# Cli Entry Point

main := (
   (local inputs)
   (local args)

   (local mode)
   (set mode Compile)

   (set args (tail argv))

   (while args (match args (
      ()
      ( ('-o (tgt remainder)) (
         (set cli-config ( cli-config (Target tgt)))
         (set args remainder)
      ))
      ( ('--compile remainder) (
         (set mode Compile)
         (set args remainder)
      ))
      ( ('--strict remainder) (
         (set config-strict True)
         (set args remainder)
      ))
      ( ('--parse remainder) (
         (set mode Parse)
         (set args remainder)
      ))
      ( ('--nostd remainder) (
         (set config-strict True)
         (set config-nostd True)
         (set args remainder)
      ))
      ( ('--parse-expression remainder) (
         (set mode ParseExpression)
         (set args remainder)
      ))
      ( ('--tokenize remainder) (
         (set mode Tokenize)
         (set args remainder)
      ))
      ( ('--debug remainder) (
         (set config-debug True)
         (set args remainder)
      ))
      ( ('--perf remainder) (
         (set config-perf True)
         (set args remainder)
      ))
      ( ('--nomacro remainder) (
         (set config-nomacro True)
         (set args remainder)
      ))
      ( ('--typecheck remainder) (
         (set mode Typecheck)
         (set args remainder)
      ))
      ( (fp remainder) (
         (set inputs (fp inputs))
         (set args remainder)
      ))
      ( u (
         fail (UnexpectionCommand u)
      ))
   )))

   (debug-memory-usage 'main)

   (while inputs (match mode (
      ()
      (Compile (
         (parse-program (tokenize-file (head inputs)))
         (set inputs (tail inputs))
      ))
      (Parse (
         (parse-program (tokenize-file (head inputs)))
         (set inputs (tail inputs))
      ))
      (Typecheck (
         (parse-program (tokenize-file (head inputs)))
         (set inputs (tail inputs))
      ))
      (ParseExpression (
         (print-s (parse-expression (tokenize-file (head inputs))))
         (set inputs (tail inputs))
      ))
      (Tokenize (
         (print-s (tokenize-file (head inputs)))
         (set inputs (tail inputs))
      ))
      (u (
         (fail (UnknownMode u))
      ))
   )))

   (match mode (
      ()
      (Compile (tail(
         (if config-nomacro () (
            (set parse-parsed-program (preprocess parse-parsed-program))
         ))
         (if config-strict (typecheck parse-parsed-program) ())
         (assemble parse-parsed-program)
      )))
      (Parse (tail(
         (if config-nomacro () (
            (set parse-parsed-program (preprocess parse-parsed-program))
         ))
         (print-s parse-parsed-program)
      )))
      (Typecheck (tail(
         (if config-nomacro () (
            (set parse-parsed-program (preprocess parse-parsed-program))
         ))
         (if config-strict (typecheck parse-parsed-program) ())
         (print-s (typecheck-show-ascript parse-parsed-program))
      )))
   ))
);

