#include "modules.h"

COMPILER Modules

ModuleRecord module;

int nextToken()
{
  scanner->ResetPeek();
  return scanner->Peek()->kind;
}

bool checkParametersList()
{
    return la->kind == _ident && nextToken() == _lparen;
}

CHARACTERS
  letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
  digit = "0123456789".
  any = ANY - '"'.
  cr  = '\r'.
  lf  = '\n'.
  tab = '\t'.
  

TOKENS
  string = '"' { any } '"'.
  ident = (letter | '_') {letter | digit | '_'}.
  lparen = '('. 
  tagcolon   = "::".
  

COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf

IGNORE cr + lf + tab

PRODUCTIONS

Block = 
'{'
    {       string
        |   Block 
        |   ANY
    }
'}'.

Modules = 
{
        ModulesInterface
    |   SkipXreateOperators
}.

ModulesInterface = "module"          (. Expression query;          .)
  [ tagcolon MetaSimpExpr<query>     (. module.addProperty(query); .)
  {';' MetaSimpExpr<query>           (. module.addProperty(query); .)
  }]
  ('{' {ModulesStatement} '}' | '.').


ModulesStatement =                              (. std::wstring path; Expression query; .)
(   "require" '(' MetaSimpExpr<query> ')' '.'   (. module.addRequest(query); .)
  | "controller" '(' string                     (. module.addControllerPath(Atom<String_t>(t->val).get()); .)
      ')' '.'
  | "discover" '(' string                       (. module.addDiscoveryPath(Atom<String_t>(t->val).get()); .)
      ')' '.'
).

MetaSimpExpr<Expression& e>=            (. Expression e2; .)
( '-' MetaSimpExpr<e2>                  (. e = Expression(Operator::NEG, {e2}); .)
| ident                                 (. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(t->val))}); .)
    ['('  MetaCalleeParams<e>  ')' ]
).

MetaCalleeParams<Expression& e> = (. Expression e2; .)
  MetaSimpExpr<e2>	     	(. e.addArg(Expression(e2)); .)
  {',' MetaSimpExpr<e2>		(. e.addArg(Expression(e2)); .)
  }.

  
  
SkipXreateOperators =
{     "rule" {ANY} Block 
    | "interface" {ANY} Block 
    | "import" {ANY} '.'
    | "case" "context" {ANY} Block 
    | ident '=' 
        (   
            "function" {ANY} Block
        |   "type" {ANY} '.'
        )
}.



END Modules.
