예제 #1
0
        public random_value getrand(string name)
        {
            Parser_Value v = getval(name);

            Misc.assert((v.spec.type & ~PARSE_T.OPT) == PARSE_T.RAND);
            return((random_value)v.value);
        }
예제 #2
0
        /** Returns the string named `name`. This symbol must exist. */
        public string getstr(string name)
        {
            Parser_Value v = getval(name);

            Misc.assert((v.spec.type & ~PARSE_T.OPT) == PARSE_T.STR);
            return((string)v.value);
        }
예제 #3
0
        public char getchar(string name)
        {
            Parser_Value v = getval(name);

            Misc.assert((v.spec.type & ~PARSE_T.OPT) == PARSE_T.CHAR);
            return((char)v.value);
        }
예제 #4
0
        public uint getuint(string name)
        {
            Parser_Value v = getval(name);

            Misc.assert((v.spec.type & ~PARSE_T.OPT) == PARSE_T.UINT);
            return((uint)v.value);
        }
예제 #5
0
        /* This is a bit long and should probably be refactored a bit. */
        public Error Parse(string line)
        {
            /*struct parser_hook *h;
             * struct parser_spec *s;
             * struct parser_value *v;
             * char *sp = null;*/

            //assert(p); //lol, C is so silly
            Misc.assert(line != null);

            freeold();

            lineno++;
            colno = 1;

            values.Clear();

            // Ignore empty lines and comments.
            line = line.Trim();
            if (line.Length == 0 || line[0] == '#')
            {
                return(Error.NONE);
            }

            string[] tok = line.Split(new char[] { ':' });
            //If we have an empty, remove it and add ":" to the next entry
            //This also has the side effect of concatinating two empties into a single :, which is what we want.
            //since two empties means it was a ":::" which mean a ":" char.
            List <string> temp_tok = new List <string>(tok);

            for (int i = 0; i < temp_tok.Count() - 1; i++)
            {
                if (temp_tok[i].Length == 0)
                {
                    temp_tok[i + 1] = ":" + temp_tok[i + 1];
                    temp_tok.RemoveAt(i);
                }
            }
            tok = temp_tok.ToArray();

            int tat = 0;

            if (tok.Length == 0)
            {
                error = Error.MISSING_FIELD;
                return(error);
            }

            Parser_Hook h = findhook(tok[tat++]);

            if (h == null)
            {
                error = Error.UNDEFINED_DIRECTIVE;
                return(error);
            }

            //Imma just try this from scratch
            //We wish to match each token in order
            foreach (Hook_Spec s in h.specs)
            {
                if (tat >= tok.Length)
                {
                    if ((s.type & PARSE_T.OPT) != 0)
                    {
                        break;                         //We're cool, it was optional anyways
                    }
                    else
                    {
                        return(Error.GENERIC);
                    }
                }
                string       val = tok[tat++];
                Parser_Value v   = new Parser_Value();

                PARSE_T type = s.type & ~PARSE_T.OPT;

                if (type == PARSE_T.INT)
                {
                    int t = 0;
                    if (val.StartsWith("0x"))
                    {
                        t = Convert.ToInt32(val.Substring(2), 16);
                    }
                    else if (!Int32.TryParse(val, out t))
                    {
                        return(Error.INVALID_VALUE);
                    }
                    v.value = t;
                }
                else if (type == PARSE_T.UINT)
                {
                    uint t;
                    if (!UInt32.TryParse(val, out t))
                    {
                        return(Error.INVALID_VALUE);
                    }
                    v.value = t;
                }
                else if (type == PARSE_T.CHAR)
                {
                    char t;
                    if (!Char.TryParse(val, out t))
                    {
                        return(Error.INVALID_VALUE);
                    }
                    v.value = t;
                }
                else if (type == PARSE_T.RAND)
                {
                    random_value t = new random_value();

                    Regex           r       = new Regex("[0-9]+");
                    MatchCollection matches = r.Matches(val, 0);

                    //This first boolean quickly became hacky. Todo: build better regex!
                    bool has_dice_number   = val.Contains("d") && val[0] != 'd' && val[1] != 'd';                   //begining with a d is cheating
                    bool has_Base_modifies = val.Contains("M");

                    int mat = 0;

                    t.dice = 1;
                    if (has_dice_number)
                    {
                        t.dice = int.Parse(matches[mat++].Value);
                    }

                    t.sides = int.Parse(matches[mat++].Value);

                    t.Base = 0;
                    if (has_Base_modifies)
                    {
                        t.Base = int.Parse(matches[mat++].Value);
                    }

                    v.value = t;
                }
                else if (type == PARSE_T.SYM)
                {
                    v.value = val;                     //Straight up
                }
                else if (type == PARSE_T.STR)
                {
                    string temp = val;
                    while (tat < tok.Length)
                    {
                        temp += tok[tat++];
                        if (tat < tok.Length)
                        {
                            temp += ":";
                        }
                    }
                    v.value = temp;
                }
                else
                {
                    throw new NotImplementedException();
                    //We probably got a type I have not written yet
                }

                v.spec = s;
                values.Add(v);
            }

            return(h.func(this));
        }
예제 #6
0
        /* This is a bit long and should probably be refactored a bit. */
        public Error Parse(string line)
        {
            /*struct parser_hook *h;
            struct parser_spec *s;
            struct parser_value *v;
            char *sp = null;*/

            //assert(p); //lol, C is so silly
            Misc.assert(line != null);

            freeold();

            lineno++;
            colno = 1;

            values.Clear();

            // Ignore empty lines and comments.
            line = line.Trim();
            if (line.Length == 0 || line[0] == '#'){
                return Error.NONE;
            }

            string[] tok = line.Split(new char[]{':'});
            //If we have an empty, remove it and add ":" to the next entry
            //This also has the side effect of concatinating two empties into a single :, which is what we want.
            //since two empties means it was a ":::" which mean a ":" char.
            List<string> temp_tok = new List<string>(tok);
            for(int i = 0; i < temp_tok.Count() - 1; i++) {
                if(temp_tok[i].Length == 0) {
                    temp_tok[i + 1] = ":" + temp_tok[i + 1];
                    temp_tok.RemoveAt(i);
                }
            }
            tok = temp_tok.ToArray();

            int tat = 0;

            if (tok.Length == 0) {
                error = Error.MISSING_FIELD;
                return error;
            }

            Parser_Hook h = findhook(tok[tat++]);
            if (h == null) {
                error = Error.UNDEFINED_DIRECTIVE;
                return error;
            }

            //Imma just try this from scratch
            //We wish to match each token in order
            foreach(Hook_Spec s in h.specs) {
                if(tat >= tok.Length) {
                    if((s.type & PARSE_T.OPT) != 0) {
                        break; //We're cool, it was optional anyways
                    } else {
                        return Error.GENERIC;
                    }
                }
                string val = tok[tat++];
                Parser_Value v = new Parser_Value();

                PARSE_T type = s.type & ~PARSE_T.OPT;

                if(type == PARSE_T.INT) {
                    int t = 0;
                    if(val.StartsWith("0x")) {
                        t = Convert.ToInt32(val.Substring(2), 16);
                    } else if(!Int32.TryParse(val, out t)) {
                        return Error.INVALID_VALUE;
                    }
                    v.value = t;
                } else if(type == PARSE_T.UINT) {
                    uint t;
                    if(!UInt32.TryParse(val, out t)) {
                        return Error.INVALID_VALUE;
                    }
                    v.value = t;
                } else if(type == PARSE_T.CHAR) {
                    char t;
                    if(!Char.TryParse(val, out t)) {
                        return Error.INVALID_VALUE;
                    }
                    v.value = t;
                } else if(type == PARSE_T.RAND) {
                    random_value t = new random_value();

                    Regex r = new Regex("[0-9]+");
                    MatchCollection matches = r.Matches(val, 0);

                    //This first boolean quickly became hacky. Todo: build better regex!
                    bool has_dice_number = val.Contains("d") && val[0] != 'd' && val[1] != 'd'; //begining with a d is cheating
                    bool has_Base_modifies = val.Contains("M");

                    int mat = 0;

                    t.dice = 1;
                    if(has_dice_number) {
                        t.dice = int.Parse(matches[mat++].Value);
                    }

                    t.sides = int.Parse(matches[mat++].Value);

                    t.Base = 0;
                    if(has_Base_modifies) {
                        t.Base = int.Parse(matches[mat++].Value);
                    }

                    v.value = t;
                } else if(type == PARSE_T.SYM) {
                    v.value = val; //Straight up
                } else if (type == PARSE_T.STR){
                    string temp = val;
                    while(tat < tok.Length) {
                        temp += tok[tat++];
                        if(tat < tok.Length) {
                            temp += ":";
                        }
                    }
                    v.value = temp;
                } else {
                    throw new NotImplementedException();
                    //We probably got a type I have not written yet
                }

                v.spec = s;
                values.Add(v);
            }

            return h.func(this);
        }