src/commands.cc

changeset 82
841562f5a32f
parent 79
2425fa6a4f21
child 85
264a61e9eba0
equal deleted inserted replaced
81:071715c17296 82:841562f5a32f
38 #include "lexer.h" 38 #include "lexer.h"
39 39
40 static list<command_info*> g_commands; 40 static list<command_info*> g_commands;
41 41
42 // ============================================================================ 42 // ============================================================================
43 // Reads command definitions from commands.def and stores them to memory. 43 //
44 void init_commands () 44 void add_command_definition (command_info* comm)
45 { 45 {
46 lexer lx; 46 // Ensure that there is no conflicts
47 lx.process_file ("commands.def"); 47 for (command_info* it : g_commands)
48 if (it->number == comm->number)
49 error ("Attempted to redefine command #%1 (%2) as %3",
50 g_commands[comm->number]->name, comm->name);
48 51
49 while (lx.get_next()) 52 g_commands << comm;
50 {
51 command_info* comm = new command_info;
52
53 // Number
54 lx.must_be (tk_number);
55 comm->number = lx.get_token()->text.to_long();
56
57 lx.must_get_next (tk_colon);
58
59 // Name
60 lx.must_get_next (tk_symbol);
61 comm->name = lx.get_token()->text;
62
63 if (IsKeyword (comm->name))
64 error ("command name `%1` conflicts with keyword", comm->name);
65
66 lx.must_get_next (tk_colon);
67
68 // Return value
69 lx.must_get_any_of ({tk_int, tk_void, tk_bool, tk_str});
70 comm->returnvalue = GetTypeByName (lx.get_token()->text); // TODO
71 assert (comm->returnvalue != -1);
72
73 lx.must_get_next (tk_colon);
74
75 // Num args
76 lx.must_get_next (tk_number);
77 comm->numargs = lx.get_token()->text.to_long();
78
79 lx.must_get_next (tk_colon);
80
81 // Max args
82 lx.must_get_next (tk_number);
83 comm->maxargs = lx.get_token()->text.to_long();
84
85 // Argument types
86 int curarg = 0;
87
88 while (curarg < comm->maxargs)
89 {
90 command_argument arg;
91 lx.must_get_next (tk_colon);
92 lx.must_get_any_of ({tk_int, tk_bool, tk_str});
93 type_e type = GetTypeByName (lx.get_token()->text);
94 assert (type != -1 && type != TYPE_VOID);
95 arg.type = type;
96
97 lx.must_get_next (tk_paren_start);
98 lx.must_get_next (tk_symbol);
99 arg.name = lx.get_token()->text;
100
101 // If this is an optional parameter, we need the default value.
102 if (curarg >= comm->numargs)
103 {
104 lx.must_get_next (tk_assign);
105
106 switch (type)
107 {
108 case TYPE_INT:
109 case TYPE_BOOL:
110 lx.must_get_next (tk_number);
111 break;
112
113 case TYPE_STRING:
114 lx.must_get_next (tk_string);
115 break;
116
117 case TYPE_UNKNOWN:
118 case TYPE_VOID:
119 break;
120 }
121
122 arg.defvalue = lx.get_token()->text.to_long();
123 }
124
125 lx.must_get_next (tk_paren_end);
126 comm->args << arg;
127 curarg++;
128 }
129
130 g_commands << comm;
131 }
132
133 if (g_commands.is_empty())
134 error ("no commands defined!\n");
135
136 print ("%1 command definitions read.\n", g_commands.size());
137 } 53 }
138 54
139 // ============================================================================ 55 // ============================================================================
140 // Finds a command by name 56 // Finds a command by name
141 command_info* find_command_by_name (string fname) 57 command_info* find_command_by_name (string fname)

mercurial