130fa30b1SMasatake YAMATO /*
230fa30b1SMasatake YAMATO * Copyright (c) 2020, Masatake YAMATO
330fa30b1SMasatake YAMATO * Copyright (c) 2020, Red Hat, Inc.
430fa30b1SMasatake YAMATO *
530fa30b1SMasatake YAMATO * This source code is released for free distribution under the terms of the
630fa30b1SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
730fa30b1SMasatake YAMATO *
830fa30b1SMasatake YAMATO * This module contains functions for generating tags for R6Class.
930fa30b1SMasatake YAMATO * https://www.rdocumentation.org/packages/R6/versions/2.4.1/topics/R6Class
1030fa30b1SMasatake YAMATO */
1130fa30b1SMasatake YAMATO
1230fa30b1SMasatake YAMATO
1330fa30b1SMasatake YAMATO /*
1430fa30b1SMasatake YAMATO * INCLUDE FILES
1530fa30b1SMasatake YAMATO */
1630fa30b1SMasatake YAMATO #include "general.h" /* must always come first */
1730fa30b1SMasatake YAMATO
1830fa30b1SMasatake YAMATO #include "r.h"
1930fa30b1SMasatake YAMATO #include "kind.h"
2030fa30b1SMasatake YAMATO #include "parse.h"
2130fa30b1SMasatake YAMATO #include "entry.h"
2230fa30b1SMasatake YAMATO #include "tokeninfo.h"
2330fa30b1SMasatake YAMATO #include "read.h"
2430fa30b1SMasatake YAMATO
2530fa30b1SMasatake YAMATO #include <string.h>
2630fa30b1SMasatake YAMATO
2730fa30b1SMasatake YAMATO
2830fa30b1SMasatake YAMATO /*
2930fa30b1SMasatake YAMATO * DATA DECLARATIONS
3030fa30b1SMasatake YAMATO */
3130fa30b1SMasatake YAMATO
3230fa30b1SMasatake YAMATO struct r6Subparser {
3330fa30b1SMasatake YAMATO rSubparser r;
3430fa30b1SMasatake YAMATO const char * access;
3530fa30b1SMasatake YAMATO bool activeBinding;
3630fa30b1SMasatake YAMATO };
3730fa30b1SMasatake YAMATO
3830fa30b1SMasatake YAMATO /*
3930fa30b1SMasatake YAMATO * FUNCTION PROTOTYPES
4030fa30b1SMasatake YAMATO */
4130fa30b1SMasatake YAMATO
4230fa30b1SMasatake YAMATO static int r6ReadRightSideSymbol (rSubparser *s,
4330fa30b1SMasatake YAMATO tokenInfo *const symbol,
4430fa30b1SMasatake YAMATO const char *const assignmentOperator,
4530fa30b1SMasatake YAMATO int parent,
4630fa30b1SMasatake YAMATO tokenInfo *const token);
4730fa30b1SMasatake YAMATO static int r6MakeTagWithTranslation (rSubparser *s,
4830fa30b1SMasatake YAMATO tokenInfo *const token,
4930fa30b1SMasatake YAMATO int parent,
5030fa30b1SMasatake YAMATO bool in_func,
5130fa30b1SMasatake YAMATO int kindInR,
5230fa30b1SMasatake YAMATO const char *const assignmentOperator);
5330fa30b1SMasatake YAMATO static bool r6AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe);
54582f04dcSMasatake YAMATO static bool r6HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e);
5530fa30b1SMasatake YAMATO
5630fa30b1SMasatake YAMATO static void parseClass (rSubparser *s, tokenInfo *const token, int classIndex);
5730fa30b1SMasatake YAMATO
5830fa30b1SMasatake YAMATO
5930fa30b1SMasatake YAMATO /*
6030fa30b1SMasatake YAMATO * DATA DEFINITIONS
6130fa30b1SMasatake YAMATO */
6230fa30b1SMasatake YAMATO
6330fa30b1SMasatake YAMATO typedef enum {
6430fa30b1SMasatake YAMATO R6_K_CLASS,
6530fa30b1SMasatake YAMATO R6_K_METHOD,
6630fa30b1SMasatake YAMATO R6_K_FIELD,
6730fa30b1SMasatake YAMATO R6_K_ACTIVE_BINDING_FUNCTION,
6830fa30b1SMasatake YAMATO } r6Kind;
6930fa30b1SMasatake YAMATO
7030fa30b1SMasatake YAMATO static kindDefinition R6Kinds[] = {
7130fa30b1SMasatake YAMATO { true, 'c', "class", "classes" },
7230fa30b1SMasatake YAMATO { true, 'm', "method", "methods" },
7330fa30b1SMasatake YAMATO { true, 'f', "field", "fields" },
7430fa30b1SMasatake YAMATO { true, 'a', "activeBindingFunc", "active binding functions" },
7530fa30b1SMasatake YAMATO };
7630fa30b1SMasatake YAMATO
7730fa30b1SMasatake YAMATO static struct r6Subparser r6Subparser = {
7830fa30b1SMasatake YAMATO .r = {
7930fa30b1SMasatake YAMATO .subparser = {
8030fa30b1SMasatake YAMATO .direction = SUBPARSER_BI_DIRECTION,
8130fa30b1SMasatake YAMATO },
8230fa30b1SMasatake YAMATO .readRightSideSymbol = r6ReadRightSideSymbol,
8330fa30b1SMasatake YAMATO .makeTagWithTranslation = r6MakeTagWithTranslation,
8430fa30b1SMasatake YAMATO .askTagAcceptancy = r6AskTagAcceptancy,
85582f04dcSMasatake YAMATO .hasFunctionAlikeKind = r6HasFunctionAlikeKind,
8630fa30b1SMasatake YAMATO },
8730fa30b1SMasatake YAMATO .access = NULL,
8830fa30b1SMasatake YAMATO .activeBinding = false,
8930fa30b1SMasatake YAMATO };
9030fa30b1SMasatake YAMATO
9130fa30b1SMasatake YAMATO
9230fa30b1SMasatake YAMATO /*
9330fa30b1SMasatake YAMATO * FUNCTION DEFINITIONS
9430fa30b1SMasatake YAMATO */
9530fa30b1SMasatake YAMATO
9630fa30b1SMasatake YAMATO /*
9730fa30b1SMasatake YAMATO * parse this area: V======V
9830fa30b1SMasatake YAMATO * klass = R6Class("klass", ..., inherit=parent)
9930fa30b1SMasatake YAMATO */
parseInherit(rSubparser * s,tokenInfo * const token,int classIndex)10030fa30b1SMasatake YAMATO static void parseInherit (rSubparser *s,
10130fa30b1SMasatake YAMATO tokenInfo *const token, int classIndex)
10230fa30b1SMasatake YAMATO {
10330fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
10430fa30b1SMasatake YAMATO if (tokenIsTypeVal (token, '='))
10530fa30b1SMasatake YAMATO {
10630fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
10730fa30b1SMasatake YAMATO if (tokenIsType (token, R_SYMBOL))
10830fa30b1SMasatake YAMATO {
10930fa30b1SMasatake YAMATO tagEntryInfo *e = getEntryInCorkQueue (classIndex);
11030fa30b1SMasatake YAMATO e->extensionFields.inheritance = vStringStrdup (token->string);
11130fa30b1SMasatake YAMATO }
11230fa30b1SMasatake YAMATO else
11330fa30b1SMasatake YAMATO tokenUnread (token);
11430fa30b1SMasatake YAMATO }
11530fa30b1SMasatake YAMATO else
11630fa30b1SMasatake YAMATO tokenUnread (token);
11730fa30b1SMasatake YAMATO }
11830fa30b1SMasatake YAMATO
11930fa30b1SMasatake YAMATO /*
12030fa30b1SMasatake YAMATO * parse this area: V===V V===V V===V
12130fa30b1SMasatake YAMATO * klass = R6Class("klass", public=list(...), private=list(...), active=list(...), ...)
12230fa30b1SMasatake YAMATO */
parseListMain(rSubparser * s,tokenInfo * const token,int classIndex,const char * access,bool activeBinding)12330fa30b1SMasatake YAMATO static void parseListMain (rSubparser *s,
12430fa30b1SMasatake YAMATO tokenInfo *const token, int classIndex, const char *access,
12530fa30b1SMasatake YAMATO bool activeBinding)
12630fa30b1SMasatake YAMATO {
12730fa30b1SMasatake YAMATO const char *last_access = ((struct r6Subparser *)s)->access;
12830fa30b1SMasatake YAMATO ((struct r6Subparser *)s)->access = access;
12930fa30b1SMasatake YAMATO
13030fa30b1SMasatake YAMATO bool last_active_binding = ((struct r6Subparser *)s)->activeBinding;
13130fa30b1SMasatake YAMATO ((struct r6Subparser *)s)->activeBinding = activeBinding;
13230fa30b1SMasatake YAMATO
13330fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
13430fa30b1SMasatake YAMATO
13519bff7a2SMasatake YAMATO while (! tokenIsTypeVal (token, ')'))
13630fa30b1SMasatake YAMATO {
13719bff7a2SMasatake YAMATO if (!rParseStatement (token, classIndex, false))
13819bff7a2SMasatake YAMATO break;
13919bff7a2SMasatake YAMATO else if (tokenIsTypeVal (token, '\n'))
14030fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
14130fa30b1SMasatake YAMATO }
14230fa30b1SMasatake YAMATO ((struct r6Subparser *)s)->access = last_access;
14330fa30b1SMasatake YAMATO ((struct r6Subparser *)s)->activeBinding = last_active_binding;
14430fa30b1SMasatake YAMATO }
14530fa30b1SMasatake YAMATO
14630fa30b1SMasatake YAMATO /*
14730fa30b1SMasatake YAMATO * parse this area: V=====|---V V=====|---V V=====|---V
14830fa30b1SMasatake YAMATO * klass = R6Class("klass", public=list(...), private=list(...), active=list(...), ...)
14930fa30b1SMasatake YAMATO */
parseList(rSubparser * s,tokenInfo * const token,int classIndex,const char * access,bool activeBinding)15030fa30b1SMasatake YAMATO static void parseList (rSubparser *s,
15130fa30b1SMasatake YAMATO tokenInfo *const token, int classIndex, const char *access,
15230fa30b1SMasatake YAMATO bool activeBinding)
15330fa30b1SMasatake YAMATO {
15430fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
15530fa30b1SMasatake YAMATO if (tokenIsTypeVal (token, '='))
15630fa30b1SMasatake YAMATO {
15730fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
158*2b000035SMasatake YAMATO if (tokenIsKeyword (token, R_LIST))
15930fa30b1SMasatake YAMATO {
16030fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
16130fa30b1SMasatake YAMATO if (tokenIsTypeVal (token, '('))
16230fa30b1SMasatake YAMATO parseListMain (s, token, classIndex, access, activeBinding);
16330fa30b1SMasatake YAMATO else
16430fa30b1SMasatake YAMATO tokenUnread (token);
16530fa30b1SMasatake YAMATO }
16630fa30b1SMasatake YAMATO else
16730fa30b1SMasatake YAMATO tokenUnread (token);
16830fa30b1SMasatake YAMATO }
16930fa30b1SMasatake YAMATO else
17030fa30b1SMasatake YAMATO tokenUnread (token);
17130fa30b1SMasatake YAMATO }
17230fa30b1SMasatake YAMATO
17330fa30b1SMasatake YAMATO /*
17430fa30b1SMasatake YAMATO * parse this area: V=======|----V=======|----V======|----V=======|----V
17530fa30b1SMasatake YAMATO * klass = R6Class("klass", public=..., private=..., active=..., inherit=...)
17630fa30b1SMasatake YAMATO */
parseClass(rSubparser * s,tokenInfo * const token,int classIndex)17730fa30b1SMasatake YAMATO static void parseClass (rSubparser *s,
17830fa30b1SMasatake YAMATO tokenInfo *const token, int classIndex)
17930fa30b1SMasatake YAMATO {
18030fa30b1SMasatake YAMATO do
18130fa30b1SMasatake YAMATO {
18230fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
18330fa30b1SMasatake YAMATO
18430fa30b1SMasatake YAMATO if (tokenIsTypeVal (token, ')'))
18530fa30b1SMasatake YAMATO break;
18630fa30b1SMasatake YAMATO else if (tokenIsTypeVal (token, '('))
18730fa30b1SMasatake YAMATO tokenSkipOverPair (token);
18830fa30b1SMasatake YAMATO else if (tokenIsTypeVal (token, '{'))
18930fa30b1SMasatake YAMATO tokenSkipOverPair (token);
19030fa30b1SMasatake YAMATO else if (tokenIsTypeVal (token, '['))
19130fa30b1SMasatake YAMATO tokenSkipOverPair (token);
19230fa30b1SMasatake YAMATO else if (tokenIsType (token, R_SYMBOL))
19330fa30b1SMasatake YAMATO {
19430fa30b1SMasatake YAMATO const char *str = tokenString (token);
19530fa30b1SMasatake YAMATO if (strcmp (str, "inherit") == 0)
19630fa30b1SMasatake YAMATO parseInherit (s, token, classIndex);
19730fa30b1SMasatake YAMATO else if (strcmp (str, "public") == 0)
19830fa30b1SMasatake YAMATO parseList (s, token, classIndex, "public", false);
19930fa30b1SMasatake YAMATO else if (strcmp (str, "private") == 0)
20030fa30b1SMasatake YAMATO parseList (s, token, classIndex, "private", false);
20130fa30b1SMasatake YAMATO else if (strcmp (str, "active") == 0)
20230fa30b1SMasatake YAMATO parseList (s, token, classIndex, "public", true);
20330fa30b1SMasatake YAMATO }
20430fa30b1SMasatake YAMATO }
20530fa30b1SMasatake YAMATO while (!tokenIsEOF (token));
20630fa30b1SMasatake YAMATO }
20730fa30b1SMasatake YAMATO
20830fa30b1SMasatake YAMATO /*
20930fa30b1SMasatake YAMATO * V=============|-----V: parse this area
21030fa30b1SMasatake YAMATO * klass = R6Class("klass", ...)
21130fa30b1SMasatake YAMATO */
r6ReadRightSideSymbol(rSubparser * s,tokenInfo * const symbol,const char * const assignmentOperator,int parent,tokenInfo * const token)21230fa30b1SMasatake YAMATO static int r6ReadRightSideSymbol (rSubparser *s,
21330fa30b1SMasatake YAMATO tokenInfo *const symbol,
21430fa30b1SMasatake YAMATO const char *const assignmentOperator,
21530fa30b1SMasatake YAMATO int parent,
21630fa30b1SMasatake YAMATO tokenInfo *const token)
21730fa30b1SMasatake YAMATO {
21877553cd0SMasatake YAMATO tokenInfo * token0 = NULL;
21977553cd0SMasatake YAMATO tokenInfo * token1 = NULL;
22077553cd0SMasatake YAMATO if (strcmp (tokenString (token), "R6") == 0)
22177553cd0SMasatake YAMATO {
22277553cd0SMasatake YAMATO tokenInfo * token0 = rNewToken ();
22377553cd0SMasatake YAMATO tokenRead (token0);
22477553cd0SMasatake YAMATO if (!tokenIsType (token0, R_SCOPE))
22577553cd0SMasatake YAMATO goto reject;
22677553cd0SMasatake YAMATO if (strcmp (tokenString (token0), "::"))
22777553cd0SMasatake YAMATO goto reject;
22877553cd0SMasatake YAMATO
22977553cd0SMasatake YAMATO tokenInfo * token1 = rNewToken ();
23077553cd0SMasatake YAMATO tokenRead (token1);
23177553cd0SMasatake YAMATO if (!tokenIsType (token1, R_SYMBOL))
23277553cd0SMasatake YAMATO goto reject;
23377553cd0SMasatake YAMATO if (strcmp (tokenString (token1), "R6Class"))
23477553cd0SMasatake YAMATO goto reject;
23577553cd0SMasatake YAMATO tokenCopy (token, token1);
23677553cd0SMasatake YAMATO tokenDelete (token1);
23777553cd0SMasatake YAMATO tokenDelete (token0);
23877553cd0SMasatake YAMATO token0 = token1 = NULL;
23977553cd0SMasatake YAMATO }
24077553cd0SMasatake YAMATO else if (strcmp (tokenString (token), "R6Class") != 0)
24130fa30b1SMasatake YAMATO return CORK_NIL;
24277553cd0SMasatake YAMATO
24330fa30b1SMasatake YAMATO rTokenReadNoNewline (token);
24430fa30b1SMasatake YAMATO if (tokenIsTypeVal (token, '('))
24530fa30b1SMasatake YAMATO {
24630fa30b1SMasatake YAMATO int corkIndex = makeSimpleTag (symbol->string, R6_K_CLASS);
24730fa30b1SMasatake YAMATO tagEntryInfo *e = getEntryInCorkQueue (corkIndex);
24830fa30b1SMasatake YAMATO if (e)
24930fa30b1SMasatake YAMATO e->extensionFields.scopeIndex = parent;
25030fa30b1SMasatake YAMATO parseClass (s, token, corkIndex);
25130fa30b1SMasatake YAMATO return corkIndex;
25230fa30b1SMasatake YAMATO }
25330fa30b1SMasatake YAMATO return CORK_NIL;
25477553cd0SMasatake YAMATO reject:
25577553cd0SMasatake YAMATO if (token1)
25677553cd0SMasatake YAMATO tokenUnread (token1);
25777553cd0SMasatake YAMATO if (token0)
25877553cd0SMasatake YAMATO tokenUnread (token0);
25977553cd0SMasatake YAMATO /* tokenDelete accepts NULL. */
26077553cd0SMasatake YAMATO tokenDelete (token1);
26177553cd0SMasatake YAMATO tokenDelete (token0);
26277553cd0SMasatake YAMATO
26377553cd0SMasatake YAMATO return CORK_NIL;
26430fa30b1SMasatake YAMATO }
26530fa30b1SMasatake YAMATO
r6MakeTagWithTranslation(rSubparser * s,tokenInfo * const token,int parent,bool in_func,int kindInR,const char * const assignmentOperator)26630fa30b1SMasatake YAMATO static int r6MakeTagWithTranslation (rSubparser *s,
26730fa30b1SMasatake YAMATO tokenInfo *const token,
26830fa30b1SMasatake YAMATO int parent,
26930fa30b1SMasatake YAMATO bool in_func,
27030fa30b1SMasatake YAMATO int kindInR,
27130fa30b1SMasatake YAMATO const char *const assignmentOperator)
27230fa30b1SMasatake YAMATO {
27330fa30b1SMasatake YAMATO tagEntryInfo e;
27430fa30b1SMasatake YAMATO
27530fa30b1SMasatake YAMATO initTagEntry (&e, tokenString (token),
27630fa30b1SMasatake YAMATO in_func
27730fa30b1SMasatake YAMATO ? (((struct r6Subparser*)s)->activeBinding
27830fa30b1SMasatake YAMATO ? R6_K_ACTIVE_BINDING_FUNCTION
27930fa30b1SMasatake YAMATO : R6_K_METHOD)
28030fa30b1SMasatake YAMATO : R6_K_FIELD);
28130fa30b1SMasatake YAMATO e.extensionFields.scopeIndex = parent;
28230fa30b1SMasatake YAMATO e.extensionFields.access = ((struct r6Subparser*)s)->access;
28330fa30b1SMasatake YAMATO
28430fa30b1SMasatake YAMATO return makeTagEntry (&e);
28530fa30b1SMasatake YAMATO }
28630fa30b1SMasatake YAMATO
r6AskTagAcceptancy(rSubparser * s,tagEntryInfo * pe)28730fa30b1SMasatake YAMATO static bool r6AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe)
28830fa30b1SMasatake YAMATO {
28930fa30b1SMasatake YAMATO return (pe->kindIndex == R6_K_CLASS);
29030fa30b1SMasatake YAMATO }
29130fa30b1SMasatake YAMATO
r6HasFunctionAlikeKind(rSubparser * s,tagEntryInfo * e)292582f04dcSMasatake YAMATO static bool r6HasFunctionAlikeKind (rSubparser *s,
293582f04dcSMasatake YAMATO tagEntryInfo *e)
294582f04dcSMasatake YAMATO {
295582f04dcSMasatake YAMATO return e->kindIndex == R6_K_METHOD ||
296582f04dcSMasatake YAMATO e->kindIndex == R6_K_ACTIVE_BINDING_FUNCTION;
297582f04dcSMasatake YAMATO }
298582f04dcSMasatake YAMATO
findR6Tags(void)29930fa30b1SMasatake YAMATO static void findR6Tags(void)
30030fa30b1SMasatake YAMATO {
30130fa30b1SMasatake YAMATO r6Subparser.access = NULL;
30230fa30b1SMasatake YAMATO scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
30330fa30b1SMasatake YAMATO }
30430fa30b1SMasatake YAMATO
R6ClassParser(void)30530fa30b1SMasatake YAMATO extern parserDefinition* R6ClassParser (void)
30630fa30b1SMasatake YAMATO {
30730fa30b1SMasatake YAMATO parserDefinition* const def = parserNew("R6Class");
30830fa30b1SMasatake YAMATO
30930fa30b1SMasatake YAMATO static parserDependency dependencies [] = {
31030fa30b1SMasatake YAMATO [0] = { DEPTYPE_SUBPARSER, "R", &r6Subparser },
31130fa30b1SMasatake YAMATO };
31230fa30b1SMasatake YAMATO
31330fa30b1SMasatake YAMATO def->dependencies = dependencies;
31430fa30b1SMasatake YAMATO def->dependencyCount = ARRAY_SIZE (dependencies);
31530fa30b1SMasatake YAMATO
31630fa30b1SMasatake YAMATO def->kindTable = R6Kinds;
31730fa30b1SMasatake YAMATO def->kindCount = ARRAY_SIZE(R6Kinds);
31830fa30b1SMasatake YAMATO
31930fa30b1SMasatake YAMATO def->parser = findR6Tags;
32030fa30b1SMasatake YAMATO def->useCork = CORK_QUEUE;
32130fa30b1SMasatake YAMATO
32230fa30b1SMasatake YAMATO return def;
32330fa30b1SMasatake YAMATO }
324