#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 = '('. 
  

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

IGNORE cr + lf + tab

PRODUCTIONS

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

Modules = 
{
        ModulesInterface
    |   SkipXreateOperators
}.

ModulesInterface = "module" '{'
    {ModulesStatement}
'}'.

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

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

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 
    | {ANY} '=' 
        (   
            "function" {ANY} Block
        |   "type" {ANY} '.'
        )
}.



END Modules.
