All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
compile.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <string.h>
3 #include <cassert>
4 
5 #include "compile.h"
6 #include "scanner.h"
7 
8 bool uscript::Compiler::DoCompile(const char *_source, Chunk *chunk) {
9  parser.hadError = false;
10  source = _source;
11  scanner.SetSource(_source);
12  chunk->source = source;
13 
14  SetChunk(chunk);
15 
16  Advance();
17 
18  while (!Match(uscript::TOKEN_EOF)) {
19  Declaration();
20  }
21 
22  Consume(uscript::TOKEN_EOF, "Expect end of expression.");
23 
24  Finish();
25 
26  return !parser.hadError;
27 }
28 
30  parser.hadError = false;
31  parser.panicMode = false;
32  scopeDepth = 0;
33 }
34 
36  if (Match(uscript::TOKEN_VAR)) {
37  VarDeclaration();
38  }
39  else {
40  Statement();
41  }
42 
43  if (parser.panicMode) Synchronize();
44 }
45 
47  uint8_t global = ParseVariable("Expect variable name.");
48 
49  if (Match(uscript::TOKEN_EQUAL)) {
50  Expression();
51  }
52  else {
53  EmitByte(uscript::OP_NIL);
54  }
55 
56  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after declaration");
57 
58  DefineVariable(global);
59 }
60 
62  std::string str(token->start, token->start + token->length);
63  const char *interned = DoIntern(str);
64  return MakeConstant(STRING_VAL(interned));
65 }
66 
67 uint8_t uscript::Compiler::ParseVariable(const char *errorMessage) {
68  Consume(uscript::TOKEN_IDENTIFIER, errorMessage);
69  DeclareVariable();
70  if (scopeDepth > 0) return 0; // local variable
71  return IdentifierConstant(&parser.previous); // global variable
72 }
73 
75  if (a->length != b->length) return false;
76  return memcmp(a->start, b->start, a->length) == 0;
77 }
78 
80  for (int i = locals.size() -1; i >= 0; i--) {
81  if (identifiersEqual(name, &locals[i].name)) {
82  if (locals[i].depth == -1) {
83  ErrorAt(parser.previous, "Cannot read from local variable in its own initializer.");
84  }
85  return i;
86  }
87  }
88  return -1;
89 }
90 
92  if (scopeDepth == 0) return; // global variables are implicitly declared
93 
94  Token name = parser.previous;
95  // make sure the local isn't already there
96  for (int i = locals.size()-1; i >= 0; i--) {
97  if (locals[i].depth != -1 && locals[i].depth < scopeDepth) {
98  break;
99  }
100  if (identifiersEqual(&locals[i].name, &name)) {
101  ErrorAt(parser.previous, "Variable with this name already declared in this scope.");
102  }
103  }
104 
105  AddLocal(name);
106 }
107 
109  if (locals.size() > UINT8_MAX) {
110  ErrorAt(parser.previous, "Too many local variables in one chunk.");
111  }
112  Local local;
113  local.name = name;
114  local.depth = -1;
115  locals.push_back(local);
116 }
117 
119  locals[locals.size() -1].depth = scopeDepth;
120 }
121 
122 void uscript::Compiler::DefineVariable(uint8_t global) {
123  if (scopeDepth > 0) {
124  MarkIntialized();
125  return;
126  }
127  EmitBytes(uscript::OP_DEFINE_GLOBAL, global);
128 }
129 
130 
132  parser.panicMode = false;
133 
134  while (parser.current.type != TOKEN_EOF) {
135  if (parser.previous.type == TOKEN_SEMICOLON) return;
136 
137  switch (parser.current.type) {
138  case TOKEN_CLASS:
139  case TOKEN_FUN:
140  case TOKEN_VAR:
141  case TOKEN_FOR:
142  case TOKEN_IF:
143  case TOKEN_WHILE:
144  case TOKEN_PRINT:
145  case TOKEN_RETURN:
146  return;
147  default:
148  break;
149  }
150  Advance();
151  }
152 }
153 
155  if (Match(uscript::TOKEN_PRINT)) {
156  PrintStatement();
157  }
158  else if (Match(uscript::TOKEN_FIELDS)) {
159  FieldsStatement();
160  }
161  else if (Match(uscript::TOKEN_IF)) {
162  IfStatement();
163  }
164  else if (Match(uscript::TOKEN_WHILE)) {
165  WhileStatement();
166  }
167  else if (Match(uscript::TOKEN_FOR)) {
168  ForStatement();
169  }
170  else if (Match(uscript::TOKEN_RETURN)) {
171  ReturnStatement();
172  }
173  else if (Match(uscript::TOKEN_LEFT_BRACE)) {
174  BeginScope();
175  Block();
176  EndScope();
177  }
178  else {
179  ExpressionStatement();
180  }
181 }
182 
184  int loopStart = CurrentChunk()->code.size();
185 
186  Consume(uscript::TOKEN_LEFT_PAREN, "Expect '(' after while.");
187  Expression();
188  Consume(uscript::TOKEN_RIGHT_PAREN, "Expect ')' after condition.");
189 
190  int exitJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
191 
192  EmitByte(uscript::OP_POP);
193  Statement();
194 
195  PatchJump(exitJump);
196  EmitByte(uscript::OP_POP);
197 
198  EmitLoop(loopStart);
199 }
200 
202  BeginScope();
203 
204  Consume(uscript::TOKEN_LEFT_PAREN, "Expect '(' after 'for'.");
205  if (Match(uscript::TOKEN_SEMICOLON)) {
206  // no initializer
207  }
208  else if (Match(uscript::TOKEN_VAR)) {
209  VarDeclaration();
210  }
211  else {
212  ExpressionStatement();
213  }
214 
215  int loopStart = CurrentChunk()->code.size();
216 
217  int exitJump = -1;
218  if (!Match(uscript::TOKEN_SEMICOLON)) {
219  Expression();
220  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after loop condition.");
221  exitJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
222  EmitByte(uscript::OP_POP);
223  }
224 
225  if (!Match(uscript::TOKEN_RIGHT_PAREN)) {
226  int bodyJump = EmitJump(uscript::OP_JUMP);
227  int incrementStart = CurrentChunk()->code.size();
228 
229  Expression();
230  EmitByte(uscript::OP_POP);
231 
232  Consume(uscript::TOKEN_RIGHT_PAREN, "Expect ')' after for clause.");
233 
234  EmitLoop(loopStart);
235  loopStart = incrementStart;
236  PatchJump(bodyJump);
237 
238  }
239 
240  // body of for loop
241  Statement();
242 
243  EmitLoop(loopStart);
244 
245  if (exitJump != -1) {
246  PatchJump(exitJump);
247  EmitByte(uscript::OP_POP);
248  }
249 
250  EndScope();
251 }
252 
254  if (Match(uscript::TOKEN_SEMICOLON)) {
255  EmitConstant(NIL_VAL);
256  EmitByte(uscript::OP_RETURN);
257  return;
258  }
259  Expression();
260 
261  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after return.");
262  EmitByte(uscript::OP_RETURN);
263  return;
264 }
265 
267  Consume(uscript::TOKEN_LEFT_PAREN, "Expect '(' after if.");
268  Expression();
269  Consume(uscript::TOKEN_RIGHT_PAREN, "Expect ')' after condition.");
270 
271  int thenJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
272  EmitByte(uscript::OP_POP);
273  Statement();
274  PatchJump(thenJump);
275 
276  int elseJump = EmitJump(uscript::OP_JUMP);
277  if (Match(uscript::TOKEN_ELSE)) Statement();
278  PatchJump(elseJump);
279 }
280 
281 int uscript::Compiler::EmitJump(uint8_t instruction) {
282  EmitByte(instruction);
283  EmitByte(0xff);
284  EmitByte(0xff);
285  return CurrentChunk()->code.size() - 2;
286 }
287 
289  int jump = CurrentChunk()->code.size() - offset - 2;
290 
291  if (jump > UINT16_MAX) {
292  ErrorAt(parser.previous, "Too much code to jump over.");
293  }
294 
295  CurrentChunk()->code[offset] = (jump >> 8) & 0xff;
296  CurrentChunk()->code[offset + 1] = jump & 0xff;
297 }
298 
300  while (!Check(uscript::TOKEN_RIGHT_BRACE) && !Check(uscript::TOKEN_EOF)) {
301  Declaration();
302  }
303  Consume(uscript::TOKEN_RIGHT_BRACE, "Expect '}' after block.");
304 }
305 
307  scopeDepth ++;
308 }
309 
311  scopeDepth --;
312 
313  while (locals.size() > 0 && locals[locals.size()-1].depth > scopeDepth) {
314  EmitByte(uscript::OP_POP);
315  locals.pop_back();
316  }
317 
318 }
319 
321  Expression();
322  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after value.");
323  EmitByte(uscript::OP_FIELDS);
324 }
325 
327  Expression();
328  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after value.");
329  EmitByte(uscript::OP_PRINT);
330 }
331 
333  Expression();
334  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after value.");
335  EmitByte(uscript::OP_POP);
336 }
337 
339  if (!Check(type)) return false;
340  Advance();
341  return true;
342 }
343 
345  return parser.current.type == type;
346 }
347 
348 void uscript::Compiler::EmitLoop(int loopStart) {
349  EmitByte(uscript::OP_LOOP);
350 
351  int offset = CurrentChunk()->code.size() - loopStart + 2;
352 
353  if (offset > UINT16_MAX) ErrorAt(parser.previous, "Loop body too large.");
354 
355  EmitByte((offset >> 8) & 0xff);
356  EmitByte(offset & 0xff);
357 }
358 
360  CurrentChunk()->Write(byte);
361 }
362 
363 void uscript::Compiler::EmitBytes(uint8_t bytea, uint8_t byteb) {
364  CurrentChunk()->Write(bytea);
365  CurrentChunk()->Write(byteb);
366 }
367 
368 static void PrintErrorAt(uscript::Token &token, const char *message, const char *source) {
369  std::cerr << "Error";
370  if (token.type == uscript::TOKEN_EOF) {
371  std::cerr << " at end";
372  }
373  else if (token.type == uscript::TOKEN_ERROR) {
374  // nothing
375  }
376  else {
377  std::string error(token.start, token.start + token.length);
378  std::cerr << " at " << error ;
379  }
380 
381  std::cerr << ": " << message << std::endl;
382  std::cerr << "In script: " << source << std::endl;
383  return;
384 }
385 
387  if (parser.panicMode) return;
388 
389  parser.hadError = true;
390  parser.panicMode = true;
391  PrintErrorAt(token, message, source);
392 }
393 
395  ParsePrecedence(uscript::Compiler::PREC_ASSIGNMENT);
396 }
397 
399  parser.previous = parser.current;
400 
401  while (1) {
402  parser.current = scanner.ScanToken();
403  if (parser.current.type != uscript::TOKEN_ERROR) break;
404 
405  ErrorAt(parser.current, parser.current.start);
406  }
407 }
408 
410  if (parser.current.type == type) {
411  Advance();
412  return;
413  }
414 
415  ErrorAt(parser.current, message);
416 }
417 
419  if (CurrentChunk()->code.size() == 0 || CurrentChunk()->code[CurrentChunk()->code.size()-1] != uscript::OP_RETURN) {
420  EmitConstant(NIL_VAL);
421  EmitReturn();
422  }
423 #ifdef DEBUG_PRINT_CODE
424  if (!parser.hadError) {
425  CurrentChunk()->Disassemble("code");
426  }
427 #endif
428 }
429 
431  return EmitByte(uscript::OP_RETURN);
432 }
433 
435  return EmitBytes(uscript::OP_CONSTANT, MakeConstant(value));
436 }
437 
439  int constant = CurrentChunk()->AddConstant(value);
440  if (constant > UINT8_MAX) {
441  ErrorAt(parser.previous, "Too many constants in one chunk.");
442  return 0;
443  }
444  return constant;
445 }
446 
447 void uscript::Compiler::Number(bool canAssign) {
448  // try to see if we can convert to integer
449  char *end;
450  int v_int = strtol(parser.previous.start, &end, 10 /* base 10*/);
451  if (end == parser.previous.start + parser.previous.length) {
452  return EmitConstant(INTEGER_VAL(v_int));
453  }
454  else {
455  double value = strtod(parser.previous.start, NULL);
456  EmitConstant(NUMBER_VAL(value));
457  }
458 }
459 
460 void uscript::Compiler::Grouping(bool canAssign) {
461  Expression();
462  Consume(uscript::TOKEN_RIGHT_PAREN, "Expect ')' after expression.");
463 }
464 
465 void uscript::Compiler::And(bool canAssign) {
466  int endJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
467 
468  EmitByte(uscript::OP_POP);
469 
470  ParsePrecedence(PREC_AND);
471 
472  PatchJump(endJump);
473 }
474 
476  uint8_t argCount = 0;
477  if (!Check(uscript::TOKEN_RIGHT_PAREN)) {
478  do {
479  Expression();
480  if (argCount == 255) {
481  ErrorAt(parser.previous, "Cannot have more than 255 arguments.");
482  }
483  argCount++;
484  } while (Match(uscript::TOKEN_COMMA));
485  }
486 
487  Consume(uscript::TOKEN_RIGHT_PAREN, "Expect ')' after function arguments.");
488  return argCount;
489 }
490 
491 void uscript::Compiler::Dot(bool canAssign) {
492  Consume(uscript::TOKEN_IDENTIFIER, "Expect property name after '.'.");
493  uint8_t name = IdentifierConstant(&parser.previous);
494 
495  EmitBytes(uscript::OP_GET_PROPERTY, name);
496 }
497 
498 void uscript::Compiler::Index(bool canAssign) {
499  Expression();
500  Consume(uscript::TOKEN_RIGHT_BRACKET, "Expect ']' to close index.");
501  EmitByte(uscript::OP_INDEX);
502 }
503 
504 void uscript::Compiler::Call(bool canAssign) {
505  uint8_t argCount = ArgumentList();
506  EmitBytes(uscript::OP_CALL, argCount);
507 }
508 
509 void uscript::Compiler::Or(bool canAssign) {
510  int elseJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
511  int endJump = EmitJump(uscript::OP_JUMP);
512 
513  PatchJump(elseJump);
514  EmitByte(uscript::OP_POP);
515 
516  ParsePrecedence(PREC_OR);
517  PatchJump(endJump);
518 }
519 
520 void uscript::Compiler::Unary(bool canAssign) {
521  uscript::TokenType operatorType = parser.previous.type;
522 
523  // compile the operand
524  ParsePrecedence(uscript::Compiler::PREC_UNARY);
525 
526  switch (operatorType) {
527  case uscript::TOKEN_BANG: EmitByte(uscript::OP_NOT); break;
528  case uscript::TOKEN_MINUS: EmitByte(uscript::OP_NEGATE); break;
529  case uscript::TOKEN_LENGTH: EmitByte(uscript::OP_LENGTH); break;
530  default: return; // unreachable
531  }
532 }
533 
534 void uscript::Compiler::Literal(bool canAssign) {
535  switch (parser.previous.type) {
536  case uscript::TOKEN_FALSE: EmitByte(uscript::OP_FALSE); break;
537  case uscript::TOKEN_TRUE: EmitByte(uscript::OP_TRUE); break;
538  case uscript::TOKEN_NIL: EmitByte(uscript::OP_NIL); break;
539  default:
540  return; //unreachable
541  }
542 }
543 
544 void uscript::Compiler::String(bool canAssign) {
545  std::string str(parser.previous.start+1, parser.previous.start + parser.previous.length - 1);
546  EmitConstant(STRING_VAL(DoIntern(str)));
547 }
548 
549 void uscript::Compiler::Variable(bool canAssign) {
550  NamedVariable(parser.previous, canAssign);
551 }
552 
554  uint8_t getOp, setOp;
555  int arg = ResolveLocal(&name);
556  if (arg != -1) {
557  getOp = OP_GET_LOCAL;
558  setOp = OP_SET_LOCAL;
559  }
560  else {
561  arg = IdentifierConstant(&name);
562  getOp = OP_GET_GLOBAL;
563  setOp = OP_SET_GLOBAL;
564  }
565 
566  if (canAssign && Match(uscript::TOKEN_EQUAL)) {
567  Expression();
568  EmitBytes(setOp, (uint8_t)arg);
569  }
570  else {
571  EmitBytes(getOp, (uint8_t)arg);
572  }
573 }
574 
575 void uscript::Compiler::Binary(bool canAssign) {
576  uscript::TokenType operatorType = parser.previous.type;
577 
578  uscript::Compiler::ParseRule *rule = GetRule(operatorType);
579 
580  ParsePrecedence((uscript::Compiler::Precedence) (rule->precedence + 1));
581 
582  switch (operatorType) {
583  case uscript::TOKEN_PLUS: EmitByte(uscript::OP_ADD); break;
584  case uscript::TOKEN_MINUS: EmitByte(uscript::OP_SUBTRACT); break;
585  case uscript::TOKEN_STAR: EmitByte(uscript::OP_MULTIPLY); break;
586  case uscript::TOKEN_SLASH: EmitByte(uscript::OP_DIVIDE); break;
588  case uscript::TOKEN_EQUAL_EQUAL: EmitByte(uscript::OP_EQUAL); break;
589  case uscript::TOKEN_GREATER: EmitByte(uscript::OP_GREATER); break;
591  case uscript::TOKEN_LESS: EmitByte(uscript::OP_LESS); break;
593  default:
594  return; // unreachable
595  }
596 }
597 
599  Advance();
600 
601  ParseFn prefixRule = GetRule(parser.previous.type)->prefix;
602  if (prefixRule == NULL) {
603  ErrorAt(parser.previous, "Expect expression.");
604  return;
605  }
606 
607  bool canAssign = precedence <= uscript::Compiler::PREC_ASSIGNMENT;
608  (*this.*prefixRule)(canAssign);
609 
610  while (precedence <= GetRule(parser.current.type)->precedence) {
611  Advance();
612  ParseFn infixRule = GetRule(parser.previous.type)->infix;
613  (*this.*infixRule)(canAssign);
614  }
615 
616  if (canAssign && Match(uscript::TOKEN_EQUAL)) {
617  ErrorAt(parser.previous, "Invalid assignmnet target.");
618  }
619 }
620 
622  static ParseRule rules[] = {
624  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_RIGHT_PAREN
625  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_LEFT_BRACE
626  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_RIGHT_BRACE
627  { NULL, &uscript::Compiler::Index, uscript::Compiler::PREC_CALL }, // TOKEN_LEFT_BRACKET
628  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_RIGHT_BRACKET
629  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_COMMA
630  { NULL, &uscript::Compiler::Dot, uscript::Compiler::PREC_CALL }, // TOKEN_DOT
633  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_SEMICOLON
636  { &uscript::Compiler::Unary, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_BANG
637  { NULL, &uscript::Compiler::Binary, uscript::Compiler::PREC_EQUALITY }, // TOKEN_BANG_EQUAL
638  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_EQUAL
639  { NULL, &uscript::Compiler::Binary, uscript::Compiler::PREC_EQUALITY }, // TOKEN_EQUAL_EQUAL
641  { NULL, &uscript::Compiler::Binary, uscript::Compiler::PREC_COMPARISON }, // TOKEN_GREATER_EQUAL
643  { NULL, &uscript::Compiler::Binary, uscript::Compiler::PREC_COMPARISON }, // TOKEN_LESS_EQUAL
644  { &uscript::Compiler::Variable, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_IDENTIFIER
645  { &uscript::Compiler::String, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_STRING
646  { &uscript::Compiler::Number, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_NUMBER
647  { NULL, &uscript::Compiler::And, uscript::Compiler::PREC_AND }, // TOKEN_AND
648  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_CLASS
649  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_ELSE
650  { &uscript::Compiler::Literal, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_FALSE
651  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_FOR
652  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_FUN
653  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_IF
655  { NULL, &uscript::Compiler::Or, uscript::Compiler::PREC_OR }, // TOKEN_OR
656  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_PRINT
657  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_RETURN
658  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_SUPER
659  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_THIS
661  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_VAR
662  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_WHILE
663  { &uscript::Compiler::Unary, NULL, uscript::Compiler::PREC_NONE }, // TOKEN LENGTH
664  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_FIELDS
665  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_ERROR
666  { NULL, NULL, uscript::Compiler::PREC_NONE }, // TOKEN_EOF
667  };
668 
669  return &rules[type];
670 
671 }
672 
673 const char *uscript::Compiler::DoIntern(const std::string &str) {
674  auto ret = strings.insert(str);
675  return ret.first->c_str();
676 }
677 
678 void uscript::Compiler::DoRegister(const char *classname) {
679  uscript::TClassInfo *ret = tclasslist.Add(classname);
680  if (ret == NULL) {
681  std::cerr << "Missing class definition for cpp class: " << classname << std::endl;
682  }
683  assert(ret != NULL);
684 }
685 
bool Check(TokenType type)
Definition: compile.cc:344
const char * DoIntern(const std::string &str)
Definition: compile.cc:673
void Expression()
Definition: compile.cc:394
void ReturnStatement()
Definition: compile.cc:253
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
Definition: CORSIKAGen.fcl:7
void AddLocal(Token name)
Definition: compile.cc:108
uint8_t IdentifierConstant(Token *token)
Definition: compile.cc:61
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void EmitLoop(int loopStart)
Definition: compile.cc:348
void DefineVariable(uint8_t global)
Definition: compile.cc:122
BEGIN_PROLOG could also be cerr
void Call(bool canAssign)
Definition: compile.cc:504
void Index(bool canAssign)
Definition: compile.cc:498
bool DoCompile(const char *_source, Chunk *chunk)
Definition: compile.cc:8
void DeclareVariable()
Definition: compile.cc:91
static bool identifiersEqual(uscript::Token *a, uscript::Token *b)
Definition: compile.cc:74
void SetSource(const char *_start)
Definition: scanner.cc:11
do source
const char * source
Definition: compile.h:58
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void Literal(bool canAssign)
Definition: compile.cc:534
uint8_t ParseVariable(const char *errorMessage)
Definition: compile.cc:67
void Binary(bool canAssign)
Definition: compile.cc:575
void BeginScope()
Definition: compile.cc:306
void PrintStatement()
Definition: compile.cc:326
void MarkIntialized()
Definition: compile.cc:118
int EmitJump(uint8_t instruction)
Definition: compile.cc:281
void PatchJump(int offset)
Definition: compile.cc:288
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
void NamedVariable(Token token, bool canAssign)
Definition: compile.cc:553
void Dot(bool canAssign)
Definition: compile.cc:491
void IfStatement()
Definition: compile.cc:266
process_name gaushit a
TokenType type
Definition: scanner.h:39
then local
void Or(bool canAssign)
Definition: compile.cc:509
int ResolveLocal(Token *name)
Definition: compile.cc:79
void FieldsStatement()
Definition: compile.cc:320
void Declaration()
Definition: compile.cc:35
void ForStatement()
Definition: compile.cc:201
void EmitConstant(Value value)
Definition: compile.cc:434
void SetChunk(Chunk *chunk)
Definition: compile.h:122
Scanner scanner
Definition: compile.h:51
uint8_t MakeConstant(Value value)
Definition: compile.cc:438
uint8_t ArgumentList()
Definition: compile.cc:475
#define NIL_VAL
Definition: value.h:46
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
bool Match(TokenType type)
Definition: compile.cc:338
#define STRING_VAL(value)
Definition: value.h:49
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
void DoRegister(const char *classname)
Definition: compile.cc:678
void Grouping(bool canAssign)
Definition: compile.cc:460
#define NUMBER_VAL(value)
Definition: value.h:47
#define INTEGER_VAL(value)
Definition: value.h:48
TokenType
Definition: scanner.h:8
void WhileStatement()
Definition: compile.cc:183
void Synchronize()
Definition: compile.cc:131
void Number(bool canAssign)
Definition: compile.cc:447
byte_as<> byte
Type of data size stored in bytes, in long long precision.
Definition: datasize.h:98
void And(bool canAssign)
Definition: compile.cc:465
void Variable(bool canAssign)
Definition: compile.cc:549
static void PrintErrorAt(uscript::Token &token, const char *message, const char *source)
Definition: compile.cc:368
void String(bool canAssign)
Definition: compile.cc:544
void Unary(bool canAssign)
Definition: compile.cc:520
void ParsePrecedence(Precedence precedence)
Definition: compile.cc:598
then echo fcl name
temporary value
const char * start
Definition: scanner.h:40
void Statement()
Definition: compile.cc:154
Parser parser
Definition: compile.h:50
std::string source
Definition: chunk.h:51
void ExpressionStatement()
Definition: compile.cc:332
ParseRule * GetRule(TokenType type) const
Definition: compile.cc:621
void VarDeclaration()
Definition: compile.cc:46
void(Compiler::*)(bool) ParseFn
Definition: compile.h:35
void EmitReturn()
Definition: compile.cc:430