static void killCurrentState ( void ) { /* Tracking the kind of previous strong * context, if it doesn't match with a * really strong entity, repop */ switch (popStrongContext ()) { case ContextValue: popStrongContext (); break; case ContextFunction: popStrongContext (); break; case ContextMethod: popStrongContext (); break; case ContextType: popStrongContext(); break; case ContextBlock: break; case ContextModule: break; case ContextClass: break; default: /* nothing more */ break; } }
/* * Parse a record type * type ident = // parsed previously * { * ident1: type1; * ident2: type2; * } */ static void typeRecord (vString * const ident, ocaToken what) { switch (what) { case OcaIDENTIFIER: addTag (ident, K_RECORDFIELD); terminatingToken = Tok_CurlR; waitedToken = Tok_semi; comeAfter = &typeRecord; toDoNext = &tillTokenOrTerminatingOrFallback; break; case OcaKEYWORD_mutable: /* ignore it */ break; case Tok_CurlR: popStrongContext (); toDoNext = &globalScope; break; default: /* don't care */ break; } }
/* Handle a method ... class declaration. * nearly a copy/paste of globalLet. */ static void methodDecl (vString * const ident, ocaToken what) { switch (what) { case Tok_PARL: /* We ignore this token to be able to parse such * declarations : * let (ident : type) = ... */ break; case OcaKEYWORD_mutable: case OcaKEYWORD_virtual: case OcaKEYWORD_rec: /* just ignore to be able to parse such declarations: * let rec ident = ... */ break; case OcaIDENTIFIER: addTag (ident, K_METHOD); /* Normal pushing to get good subs */ pushStrongContext (ident, ContextMethod); /*pushSoftContext( globalScope, ident, ContextMethod ); */ toDoNext = &letParam; break; case OcaKEYWORD_end: popStrongContext (); break; default: toDoNext = &globalScope; break; } }
/* Ensure a constructor is not a type path beginning * with a module */ static void constructorValidation (vString * const ident, ocaToken what) { switch (what) { case Tok_Op: /* if we got a '.' which is an operator */ toDoNext = &globalScope; popStrongContext (); needStrongPoping = FALSE; break; case OcaKEYWORD_of: /* OK, it must be a constructor :) */ if (vStringLength (tempIdent) > 0) { makeTagEntry (&tempTag); vStringClear (tempIdent); } toDoNext = &tillTokenOrFallback; comeAfter = &typeSpecification; waitedToken = Tok_Pipe; break; case Tok_Pipe: /* OK, it was a constructor :) */ if (vStringLength (tempIdent) > 0) { makeTagEntry (&tempTag); vStringClear (tempIdent); } toDoNext = &typeSpecification; break; default: /* and mean that we're not facing a module name */ if (vStringLength (tempIdent) > 0) { makeTagEntry (&tempTag); vStringClear (tempIdent); } toDoNext = &tillTokenOrFallback; comeAfter = &typeSpecification; waitedToken = Tok_Pipe; /* nothing in the context, discard it */ popStrongContext (); /* to be sure we use this token */ globalScope (ident, what); } }
static void cleanupPreviousParser ( void ) { if (needStrongPoping) { needStrongPoping = FALSE; popStrongContext (); } }
/* Ignore everything till waitedToken and jump to comeAfter. * If the "end" keyword is encountered break, doesn't remember * why though. */ static void tillToken (vString * const UNUSED (ident), ocaToken what) { if (what == waitedToken) toDoNext = comeAfter; else if (what == OcaKEYWORD_end) { popStrongContext (); toDoNext = &globalScope; } }
/** handle let inside functions (so like it's name * say : local let */ static void localLet (vString * const ident, ocaToken what) { switch (what) { case Tok_PARL: /* We ignore this token to be able to parse such * declarations : * let (ident : type) = ... */ break; case OcaKEYWORD_rec: /* just ignore to be able to parse such declarations: * let rec ident = ... */ break; case Tok_Op: /* we are defining a new operator, it's a * function definition */ if (exportLocalInfo) addTag (ident, K_FUNCTION); pushSoftContext (mayRedeclare, ident, ContextFunction); toDoNext = &letParam; break; /* Can be a weiiird binding, or an '_' */ case Tok_Val: if (exportLocalInfo) addTag (ident, K_VAR); pushSoftContext (mayRedeclare, ident, ContextValue); toDoNext = &letParam; break; case OcaIDENTIFIER: if (exportLocalInfo) addTag (ident, K_VAR); pushSoftContext (mayRedeclare, ident, ContextValue); toDoNext = &letParam; break; case OcaKEYWORD_end: popStrongContext (); break; default: toDoNext = &localScope; break; } }
/* Handle a global * let ident ... * or * let rec ident ... */ static void globalLet (vString * const ident, ocaToken what) { switch (what) { case Tok_PARL: /* We ignore this token to be able to parse such * declarations : * let (ident : type) = ... */ break; case OcaKEYWORD_mutable: case OcaKEYWORD_virtual: case OcaKEYWORD_rec: /* just ignore to be able to parse such declarations: * let rec ident = ... */ break; case Tok_Op: /* we are defining a new operator, it's a * function definition */ addTag (ident, K_FUNCTION); pushStrongContext (ident, ContextFunction); toDoNext = &letParam; break; case OcaIDENTIFIER: addTag (ident, K_VAR); pushStrongContext (ident, ContextValue); requestStrongPoping (); toDoNext = &letParam; break; case OcaKEYWORD_end: popStrongContext (); break; default: toDoNext = &globalScope; break; } }
/* Ignore everything till a waitedToken is seen, but * take care of balanced parentheses/bracket use */ static void contextualTillToken (vString * const UNUSED (ident), ocaToken what) { static int parentheses = 0; static int bracket = 0; static int curly = 0; switch (what) { case Tok_PARL: parentheses--; break; case Tok_PARR: parentheses++; break; case Tok_CurlL: curly--; break; case Tok_CurlR: curly++; break; case Tok_BRL: bracket--; break; case Tok_BRR: bracket++; break; default: /* other token are ignored */ break; } if (what == waitedToken && parentheses == 0 && bracket == 0 && curly == 0) toDoNext = comeAfter; else if (what == OcaKEYWORD_end) { popStrongContext (); toDoNext = &globalScope; } }