All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
uscript::Compiler Class Reference

#include <compile.h>

Classes

struct  Local
 
struct  Parser
 
struct  ParseRule
 

Static Public Member Functions

static const char * Intern (const std::string &str)
 
static bool HadError ()
 
static bool Compile (const char *source, Chunk *chunk)
 
static TClassInfoGetClassInfo (const char *classname)
 
template<typename TObj >
static void Register ()
 

Private Types

enum  Precedence {
  PREC_NONE, PREC_ASSIGNMENT, PREC_OR, PREC_AND,
  PREC_EQUALITY, PREC_COMPARISON, PREC_TERM, PREC_FACTOR,
  PREC_UNARY, PREC_CALL, PREC_PRIMARY
}
 
using ParseFn = void(Compiler::*)(bool)
 

Private Member Functions

void Declaration ()
 
void Statement ()
 
void Synchronize ()
 
void Block ()
 
void BeginScope ()
 
void EndScope ()
 
void VarDeclaration ()
 
uint8_t IdentifierConstant (Token *token)
 
uint8_t ParseVariable (const char *errorMessage)
 
void DefineVariable (uint8_t global)
 
void DeclareVariable ()
 
void AddLocal (Token name)
 
int ResolveLocal (Token *name)
 
void MarkIntialized ()
 
void FieldsStatement ()
 
void PrintStatement ()
 
void ExpressionStatement ()
 
void IfStatement ()
 
void WhileStatement ()
 
void ForStatement ()
 
void ReturnStatement ()
 
bool Match (TokenType type)
 
bool Check (TokenType type)
 
void ErrorAt (Token &token, const char *message)
 
void PatchJump (int offset)
 
int EmitJump (uint8_t instruction)
 
void EmitLoop (int loopStart)
 
void EmitByte (uint8_t byte)
 
void EmitBytes (uint8_t bytea, uint8_t byteb)
 
void EmitReturn ()
 
void EmitConstant (Value value)
 
uint8_t MakeConstant (Value value)
 
void Number (bool canAssign)
 
void Grouping (bool canAssign)
 
void Unary (bool canAssign)
 
void Binary (bool canAssign)
 
void Literal (bool canAssign)
 
void String (bool canAssign)
 
void Variable (bool canAssign)
 
void And (bool canAssign)
 
void Or (bool canAssign)
 
void Call (bool canAssign)
 
void Index (bool canAssign)
 
void Dot (bool canAssign)
 
void NamedVariable (Token token, bool canAssign)
 
void ParsePrecedence (Precedence precedence)
 
ParseRuleGetRule (TokenType type) const
 
uint8_t ArgumentList ()
 
void Advance ()
 
void Expression ()
 
void Consume (TokenType type, const char *message)
 
void SetChunk (Chunk *chunk)
 
void Finish ()
 
ChunkCurrentChunk ()
 
 Compiler ()
 
bool DoCompile (const char *_source, Chunk *chunk)
 
const char * DoIntern (const std::string &str)
 
void DoRegister (const char *classname)
 

Static Private Member Functions

static CompilerInstance ()
 

Private Attributes

std::unordered_set< std::string > strings
 
Parser parser
 
Scanner scanner
 
Chunkcurrent
 
std::vector< Locallocals
 
int scopeDepth
 
TClassList tclasslist
 
const char * source
 

Detailed Description

Definition at line 13 of file compile.h.

Member Typedef Documentation

using uscript::Compiler::ParseFn = void (Compiler::*)(bool)
private

Definition at line 35 of file compile.h.

Member Enumeration Documentation

Enumerator
PREC_NONE 
PREC_ASSIGNMENT 
PREC_OR 
PREC_AND 
PREC_EQUALITY 
PREC_COMPARISON 
PREC_TERM 
PREC_FACTOR 
PREC_UNARY 
PREC_CALL 
PREC_PRIMARY 

Definition at line 21 of file compile.h.

Constructor & Destructor Documentation

uscript::Compiler::Compiler ( )
private

Definition at line 29 of file compile.cc.

29  {
30  parser.hadError = false;
31  parser.panicMode = false;
32  scopeDepth = 0;
33 }
Parser parser
Definition: compile.h:50

Member Function Documentation

void uscript::Compiler::AddLocal ( Token  name)
private

Definition at line 108 of file compile.cc.

108  {
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 }
then local
std::vector< Local > locals
Definition: compile.h:53
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
then echo fcl name
Parser parser
Definition: compile.h:50
void uscript::Compiler::Advance ( )
private

Definition at line 398 of file compile.cc.

398  {
400 
401  while (1) {
403  if (parser.current.type != uscript::TOKEN_ERROR) break;
404 
406  }
407 }
TokenType type
Definition: scanner.h:39
Scanner scanner
Definition: compile.h:51
Token ScanToken()
Definition: scanner.cc:48
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
const char * start
Definition: scanner.h:40
Parser parser
Definition: compile.h:50
void uscript::Compiler::And ( bool  canAssign)
private

Definition at line 465 of file compile.cc.

465  {
466  int endJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
467 
469 
471 
472  PatchJump(endJump);
473 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
int EmitJump(uint8_t instruction)
Definition: compile.cc:281
void PatchJump(int offset)
Definition: compile.cc:288
void ParsePrecedence(Precedence precedence)
Definition: compile.cc:598
uint8_t uscript::Compiler::ArgumentList ( )
private

Definition at line 475 of file compile.cc.

475  {
476  uint8_t argCount = 0;
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 }
bool Check(TokenType type)
Definition: compile.cc:344
void Expression()
Definition: compile.cc:394
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
bool Match(TokenType type)
Definition: compile.cc:338
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
Parser parser
Definition: compile.h:50
void uscript::Compiler::BeginScope ( )
private

Definition at line 306 of file compile.cc.

306  {
307  scopeDepth ++;
308 }
void uscript::Compiler::Binary ( bool  canAssign)
private

Definition at line 575 of file compile.cc.

575  {
576  uscript::TokenType operatorType = parser.previous.type;
577 
578  uscript::Compiler::ParseRule *rule = GetRule(operatorType);
579 
581 
582  switch (operatorType) {
593  default:
594  return; // unreachable
595  }
596 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
TokenType type
Definition: scanner.h:39
TokenType
Definition: scanner.h:8
void ParsePrecedence(Precedence precedence)
Definition: compile.cc:598
Parser parser
Definition: compile.h:50
ParseRule * GetRule(TokenType type) const
Definition: compile.cc:621
void uscript::Compiler::Block ( )
private

Definition at line 299 of file compile.cc.

299  {
301  Declaration();
302  }
303  Consume(uscript::TOKEN_RIGHT_BRACE, "Expect '}' after block.");
304 }
bool Check(TokenType type)
Definition: compile.cc:344
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void Declaration()
Definition: compile.cc:35
void uscript::Compiler::Call ( bool  canAssign)
private

Definition at line 504 of file compile.cc.

504  {
505  uint8_t argCount = ArgumentList();
506  EmitBytes(uscript::OP_CALL, argCount);
507 }
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
uint8_t ArgumentList()
Definition: compile.cc:475
bool uscript::Compiler::Check ( uscript::TokenType  type)
private

Definition at line 344 of file compile.cc.

344  {
345  return parser.current.type == type;
346 }
TokenType type
Definition: scanner.h:39
Parser parser
Definition: compile.h:50
static bool uscript::Compiler::Compile ( const char *  source,
Chunk chunk 
)
inlinestatic

Definition at line 140 of file compile.h.

140 { return Instance().DoCompile(source, chunk); }
bool DoCompile(const char *_source, Chunk *chunk)
Definition: compile.cc:8
const char * source
Definition: compile.h:58
static Compiler & Instance()
Definition: compile.h:132
void uscript::Compiler::Consume ( uscript::TokenType  type,
const char *  message 
)
private

Definition at line 409 of file compile.cc.

409  {
410  if (parser.current.type == type) {
411  Advance();
412  return;
413  }
414 
416 }
TokenType type
Definition: scanner.h:39
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
Parser parser
Definition: compile.h:50
Chunk* uscript::Compiler::CurrentChunk ( )
inlineprivate

Definition at line 124 of file compile.h.

124 { return current; }
Chunk * current
Definition: compile.h:52
void uscript::Compiler::Declaration ( )
private

Definition at line 35 of file compile.cc.

35  {
38  }
39  else {
40  Statement();
41  }
42 
44 }
bool Match(TokenType type)
Definition: compile.cc:338
void Synchronize()
Definition: compile.cc:131
void Statement()
Definition: compile.cc:154
Parser parser
Definition: compile.h:50
void VarDeclaration()
Definition: compile.cc:46
void uscript::Compiler::DeclareVariable ( )
private

Definition at line 91 of file compile.cc.

91  {
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 }
void AddLocal(Token name)
Definition: compile.cc:108
static bool identifiersEqual(uscript::Token *a, uscript::Token *b)
Definition: compile.cc:74
std::vector< Local > locals
Definition: compile.h:53
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
then echo fcl name
Parser parser
Definition: compile.h:50
void uscript::Compiler::DefineVariable ( uint8_t  global)
private

Definition at line 122 of file compile.cc.

122  {
123  if (scopeDepth > 0) {
124  MarkIntialized();
125  return;
126  }
128 }
void MarkIntialized()
Definition: compile.cc:118
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
bool uscript::Compiler::DoCompile ( const char *  _source,
Chunk chunk 
)
private

Definition at line 8 of file compile.cc.

8  {
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 }
void SetSource(const char *_start)
Definition: scanner.cc:11
const char * source
Definition: compile.h:58
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void Declaration()
Definition: compile.cc:35
void SetChunk(Chunk *chunk)
Definition: compile.h:122
Scanner scanner
Definition: compile.h:51
bool Match(TokenType type)
Definition: compile.cc:338
Parser parser
Definition: compile.h:50
const char * uscript::Compiler::DoIntern ( const std::string &  str)
private

Definition at line 673 of file compile.cc.

673  {
674  auto ret = strings.insert(str);
675  return ret.first->c_str();
676 }
std::unordered_set< std::string > strings
Definition: compile.h:49
void uscript::Compiler::DoRegister ( const char *  classname)
private

Definition at line 678 of file compile.cc.

678  {
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 }
BEGIN_PROLOG could also be cerr
TClassList tclasslist
Definition: compile.h:56
TClassInfo * Add(const char *classname)
Definition: tclass.cc:16
void uscript::Compiler::Dot ( bool  canAssign)
private

Definition at line 491 of file compile.cc.

491  {
492  Consume(uscript::TOKEN_IDENTIFIER, "Expect property name after '.'.");
493  uint8_t name = IdentifierConstant(&parser.previous);
494 
496 }
uint8_t IdentifierConstant(Token *token)
Definition: compile.cc:61
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
then echo fcl name
Parser parser
Definition: compile.h:50
void uscript::Compiler::EmitByte ( uint8_t  byte)
private

Definition at line 359 of file compile.cc.

359  {
360  CurrentChunk()->Write(byte);
361 }
Chunk * CurrentChunk()
Definition: compile.h:124
void Write(uint8_t instruction)
Definition: chunk.cc:6
byte_as<> byte
Type of data size stored in bytes, in long long precision.
Definition: datasize.h:98
void uscript::Compiler::EmitBytes ( uint8_t  bytea,
uint8_t  byteb 
)
private

Definition at line 363 of file compile.cc.

363  {
364  CurrentChunk()->Write(bytea);
365  CurrentChunk()->Write(byteb);
366 }
Chunk * CurrentChunk()
Definition: compile.h:124
void Write(uint8_t instruction)
Definition: chunk.cc:6
void uscript::Compiler::EmitConstant ( Value  value)
private

Definition at line 434 of file compile.cc.

434  {
436 }
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
uint8_t MakeConstant(Value value)
Definition: compile.cc:438
temporary value
int uscript::Compiler::EmitJump ( uint8_t  instruction)
private

Definition at line 281 of file compile.cc.

281  {
282  EmitByte(instruction);
283  EmitByte(0xff);
284  EmitByte(0xff);
285  return CurrentChunk()->code.size() - 2;
286 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
Chunk * CurrentChunk()
Definition: compile.h:124
std::vector< uint8_t > code
Definition: chunk.h:52
void uscript::Compiler::EmitLoop ( int  loopStart)
private

Definition at line 348 of file compile.cc.

348  {
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 }
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
Definition: CORSIKAGen.fcl:7
void EmitByte(uint8_t byte)
Definition: compile.cc:359
Chunk * CurrentChunk()
Definition: compile.h:124
std::vector< uint8_t > code
Definition: chunk.h:52
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
Parser parser
Definition: compile.h:50
void uscript::Compiler::EmitReturn ( )
private

Definition at line 430 of file compile.cc.

430  {
432 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void uscript::Compiler::EndScope ( )
private

Definition at line 310 of file compile.cc.

310  {
311  scopeDepth --;
312 
313  while (locals.size() > 0 && locals[locals.size()-1].depth > scopeDepth) {
315  locals.pop_back();
316  }
317 
318 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
std::vector< Local > locals
Definition: compile.h:53
void uscript::Compiler::ErrorAt ( uscript::Token token,
const char *  message 
)
private

Definition at line 386 of file compile.cc.

386  {
387  if (parser.panicMode) return;
388 
389  parser.hadError = true;
390  parser.panicMode = true;
391  PrintErrorAt(token, message, source);
392 }
const char * source
Definition: compile.h:58
static void PrintErrorAt(uscript::Token &token, const char *message, const char *source)
Definition: compile.cc:368
Parser parser
Definition: compile.h:50
void uscript::Compiler::Expression ( )
private

Definition at line 394 of file compile.cc.

void uscript::Compiler::ExpressionStatement ( )
private

Definition at line 332 of file compile.cc.

332  {
333  Expression();
334  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after value.");
336 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void uscript::Compiler::FieldsStatement ( )
private

Definition at line 320 of file compile.cc.

320  {
321  Expression();
322  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after value.");
324 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void uscript::Compiler::Finish ( )
private

Definition at line 418 of file compile.cc.

418  {
419  if (CurrentChunk()->code.size() == 0 || CurrentChunk()->code[CurrentChunk()->code.size()-1] != uscript::OP_RETURN) {
421  EmitReturn();
422  }
423 #ifdef DEBUG_PRINT_CODE
424  if (!parser.hadError) {
425  CurrentChunk()->Disassemble("code");
426  }
427 #endif
428 }
Chunk * CurrentChunk()
Definition: compile.h:124
std::vector< uint8_t > code
Definition: chunk.h:52
void EmitConstant(Value value)
Definition: compile.cc:434
#define NIL_VAL
Definition: value.h:46
void Disassemble(const std::string &name) const
Definition: chunk.cc:15
Parser parser
Definition: compile.h:50
void EmitReturn()
Definition: compile.cc:430
void uscript::Compiler::ForStatement ( )
private

Definition at line 201 of file compile.cc.

201  {
202  BeginScope();
203 
204  Consume(uscript::TOKEN_LEFT_PAREN, "Expect '(' after 'for'.");
206  // no initializer
207  }
208  else if (Match(uscript::TOKEN_VAR)) {
209  VarDeclaration();
210  }
211  else {
213  }
214 
215  int loopStart = CurrentChunk()->code.size();
216 
217  int exitJump = -1;
219  Expression();
220  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after loop condition.");
223  }
224 
226  int bodyJump = EmitJump(uscript::OP_JUMP);
227  int incrementStart = CurrentChunk()->code.size();
228 
229  Expression();
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);
248  }
249 
250  EndScope();
251 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void EmitLoop(int loopStart)
Definition: compile.cc:348
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void BeginScope()
Definition: compile.cc:306
int EmitJump(uint8_t instruction)
Definition: compile.cc:281
void PatchJump(int offset)
Definition: compile.cc:288
Chunk * CurrentChunk()
Definition: compile.h:124
std::vector< uint8_t > code
Definition: chunk.h:52
bool Match(TokenType type)
Definition: compile.cc:338
void Statement()
Definition: compile.cc:154
void ExpressionStatement()
Definition: compile.cc:332
void VarDeclaration()
Definition: compile.cc:46
static TClassInfo* uscript::Compiler::GetClassInfo ( const char *  classname)
inlinestatic

Definition at line 142 of file compile.h.

142  {
143  return Instance().tclasslist.Add(classname);
144  }
static Compiler & Instance()
Definition: compile.h:132
TClassList tclasslist
Definition: compile.h:56
TClassInfo * Add(const char *classname)
Definition: tclass.cc:16
uscript::Compiler::ParseRule * uscript::Compiler::GetRule ( uscript::TokenType  type) const
private

Definition at line 621 of file compile.cc.

621  {
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 }
void Call(bool canAssign)
Definition: compile.cc:504
void Index(bool canAssign)
Definition: compile.cc:498
void Literal(bool canAssign)
Definition: compile.cc:534
void Binary(bool canAssign)
Definition: compile.cc:575
void Dot(bool canAssign)
Definition: compile.cc:491
void Or(bool canAssign)
Definition: compile.cc:509
void Grouping(bool canAssign)
Definition: compile.cc:460
void Number(bool canAssign)
Definition: compile.cc:447
void And(bool canAssign)
Definition: compile.cc:465
void Variable(bool canAssign)
Definition: compile.cc:549
void String(bool canAssign)
Definition: compile.cc:544
void Unary(bool canAssign)
Definition: compile.cc:520
void uscript::Compiler::Grouping ( bool  canAssign)
private

Definition at line 460 of file compile.cc.

460  {
461  Expression();
462  Consume(uscript::TOKEN_RIGHT_PAREN, "Expect ')' after expression.");
463 }
void Expression()
Definition: compile.cc:394
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
static bool uscript::Compiler::HadError ( )
inlinestatic

Definition at line 139 of file compile.h.

139 { return Instance().parser.hadError; }
static Compiler & Instance()
Definition: compile.h:132
Parser parser
Definition: compile.h:50
uint8_t uscript::Compiler::IdentifierConstant ( uscript::Token token)
private

Definition at line 61 of file compile.cc.

61  {
62  std::string str(token->start, token->start + token->length);
63  const char *interned = DoIntern(str);
64  return MakeConstant(STRING_VAL(interned));
65 }
const char * DoIntern(const std::string &str)
Definition: compile.cc:673
uint8_t MakeConstant(Value value)
Definition: compile.cc:438
#define STRING_VAL(value)
Definition: value.h:49
const char * start
Definition: scanner.h:40
void uscript::Compiler::IfStatement ( )
private

Definition at line 266 of file compile.cc.

266  {
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);
273  Statement();
274  PatchJump(thenJump);
275 
276  int elseJump = EmitJump(uscript::OP_JUMP);
278  PatchJump(elseJump);
279 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
int EmitJump(uint8_t instruction)
Definition: compile.cc:281
void PatchJump(int offset)
Definition: compile.cc:288
bool Match(TokenType type)
Definition: compile.cc:338
void Statement()
Definition: compile.cc:154
void uscript::Compiler::Index ( bool  canAssign)
private

Definition at line 498 of file compile.cc.

498  {
499  Expression();
500  Consume(uscript::TOKEN_RIGHT_BRACKET, "Expect ']' to close index.");
502 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
static Compiler& uscript::Compiler::Instance ( )
inlinestaticprivate

Definition at line 132 of file compile.h.

132  {
133  static Compiler c;
134  return c;
135  }
static const char* uscript::Compiler::Intern ( const std::string &  str)
inlinestatic

Definition at line 138 of file compile.h.

138 { return Instance().DoIntern(str); }
const char * DoIntern(const std::string &str)
Definition: compile.cc:673
static Compiler & Instance()
Definition: compile.h:132
void uscript::Compiler::Literal ( bool  canAssign)
private

Definition at line 534 of file compile.cc.

534  {
535  switch (parser.previous.type) {
539  default:
540  return; //unreachable
541  }
542 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
TokenType type
Definition: scanner.h:39
Parser parser
Definition: compile.h:50
uint8_t uscript::Compiler::MakeConstant ( Value  value)
private

Definition at line 438 of file compile.cc.

438  {
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 }
Chunk * CurrentChunk()
Definition: compile.h:124
unsigned AddConstant(Value constant)
Definition: chunk.cc:10
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
temporary value
Parser parser
Definition: compile.h:50
void uscript::Compiler::MarkIntialized ( )
private

Definition at line 118 of file compile.cc.

118  {
119  locals[locals.size() -1].depth = scopeDepth;
120 }
std::vector< Local > locals
Definition: compile.h:53
bool uscript::Compiler::Match ( uscript::TokenType  type)
private

Definition at line 338 of file compile.cc.

338  {
339  if (!Check(type)) return false;
340  Advance();
341  return true;
342 }
bool Check(TokenType type)
Definition: compile.cc:344
void uscript::Compiler::NamedVariable ( uscript::Token  name,
bool  canAssign 
)
private

Definition at line 553 of file compile.cc.

553  {
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 }
void Expression()
Definition: compile.cc:394
uint8_t IdentifierConstant(Token *token)
Definition: compile.cc:61
void EmitBytes(uint8_t bytea, uint8_t byteb)
Definition: compile.cc:363
int ResolveLocal(Token *name)
Definition: compile.cc:79
bool Match(TokenType type)
Definition: compile.cc:338
void uscript::Compiler::Number ( bool  canAssign)
private

Definition at line 447 of file compile.cc.

447  {
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 }
void EmitConstant(Value value)
Definition: compile.cc:434
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
#define NUMBER_VAL(value)
Definition: value.h:47
#define INTEGER_VAL(value)
Definition: value.h:48
temporary value
const char * start
Definition: scanner.h:40
Parser parser
Definition: compile.h:50
void uscript::Compiler::Or ( bool  canAssign)
private

Definition at line 509 of file compile.cc.

509  {
510  int elseJump = EmitJump(uscript::OP_JUMP_IF_FALSE);
511  int endJump = EmitJump(uscript::OP_JUMP);
512 
513  PatchJump(elseJump);
515 
517  PatchJump(endJump);
518 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
int EmitJump(uint8_t instruction)
Definition: compile.cc:281
void PatchJump(int offset)
Definition: compile.cc:288
void ParsePrecedence(Precedence precedence)
Definition: compile.cc:598
void uscript::Compiler::ParsePrecedence ( Precedence  precedence)
private

Definition at line 598 of file compile.cc.

598  {
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 }
TokenType type
Definition: scanner.h:39
bool Match(TokenType type)
Definition: compile.cc:338
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
Parser parser
Definition: compile.h:50
ParseRule * GetRule(TokenType type) const
Definition: compile.cc:621
void(Compiler::*)(bool) ParseFn
Definition: compile.h:35
uint8_t uscript::Compiler::ParseVariable ( const char *  errorMessage)
private

Definition at line 67 of file compile.cc.

67  {
68  Consume(uscript::TOKEN_IDENTIFIER, errorMessage);
70  if (scopeDepth > 0) return 0; // local variable
71  return IdentifierConstant(&parser.previous); // global variable
72 }
uint8_t IdentifierConstant(Token *token)
Definition: compile.cc:61
void DeclareVariable()
Definition: compile.cc:91
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
Parser parser
Definition: compile.h:50
void uscript::Compiler::PatchJump ( int  offset)
private

Definition at line 288 of file compile.cc.

288  {
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 }
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
Definition: CORSIKAGen.fcl:7
Chunk * CurrentChunk()
Definition: compile.h:124
std::vector< uint8_t > code
Definition: chunk.h:52
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
Parser parser
Definition: compile.h:50
void uscript::Compiler::PrintStatement ( )
private

Definition at line 326 of file compile.cc.

326  {
327  Expression();
328  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after value.");
330 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
template<typename TObj >
static void uscript::Compiler::Register ( )
inlinestatic

Definition at line 147 of file compile.h.

147  {
148  Instance().DoRegister(std::string(type_name<TObj>()).c_str());
149  }
static Compiler & Instance()
Definition: compile.h:132
void DoRegister(const char *classname)
Definition: compile.cc:678
int uscript::Compiler::ResolveLocal ( Token name)
private

Definition at line 79 of file compile.cc.

79  {
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 }
static bool identifiersEqual(uscript::Token *a, uscript::Token *b)
Definition: compile.cc:74
std::vector< Local > locals
Definition: compile.h:53
void ErrorAt(Token &token, const char *message)
Definition: compile.cc:386
then echo fcl name
Parser parser
Definition: compile.h:50
void uscript::Compiler::ReturnStatement ( )
private

Definition at line 253 of file compile.cc.

253  {
257  return;
258  }
259  Expression();
260 
261  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after return.");
263  return;
264 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
void EmitConstant(Value value)
Definition: compile.cc:434
#define NIL_VAL
Definition: value.h:46
bool Match(TokenType type)
Definition: compile.cc:338
void uscript::Compiler::SetChunk ( Chunk chunk)
inlineprivate

Definition at line 122 of file compile.h.

122 { current = chunk; }
Chunk * current
Definition: compile.h:52
void uscript::Compiler::Statement ( )
private

Definition at line 154 of file compile.cc.

154  {
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 {
180  }
181 }
void ReturnStatement()
Definition: compile.cc:253
void BeginScope()
Definition: compile.cc:306
void PrintStatement()
Definition: compile.cc:326
void IfStatement()
Definition: compile.cc:266
void FieldsStatement()
Definition: compile.cc:320
void ForStatement()
Definition: compile.cc:201
bool Match(TokenType type)
Definition: compile.cc:338
void WhileStatement()
Definition: compile.cc:183
void ExpressionStatement()
Definition: compile.cc:332
void uscript::Compiler::String ( bool  canAssign)
private

Definition at line 544 of file compile.cc.

544  {
545  std::string str(parser.previous.start+1, parser.previous.start + parser.previous.length - 1);
547 }
const char * DoIntern(const std::string &str)
Definition: compile.cc:673
void EmitConstant(Value value)
Definition: compile.cc:434
#define STRING_VAL(value)
Definition: value.h:49
const char * start
Definition: scanner.h:40
Parser parser
Definition: compile.h:50
void uscript::Compiler::Synchronize ( )
private

Definition at line 131 of file compile.cc.

131  {
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 }
TokenType type
Definition: scanner.h:39
Parser parser
Definition: compile.h:50
void uscript::Compiler::Unary ( bool  canAssign)
private

Definition at line 520 of file compile.cc.

520  {
521  uscript::TokenType operatorType = parser.previous.type;
522 
523  // compile the operand
525 
526  switch (operatorType) {
530  default: return; // unreachable
531  }
532 }
void EmitByte(uint8_t byte)
Definition: compile.cc:359
TokenType type
Definition: scanner.h:39
TokenType
Definition: scanner.h:8
void ParsePrecedence(Precedence precedence)
Definition: compile.cc:598
Parser parser
Definition: compile.h:50
void uscript::Compiler::VarDeclaration ( )
private

Definition at line 46 of file compile.cc.

46  {
47  uint8_t global = ParseVariable("Expect variable name.");
48 
50  Expression();
51  }
52  else {
54  }
55 
56  Consume(uscript::TOKEN_SEMICOLON, "Expect ';' after declaration");
57 
58  DefineVariable(global);
59 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void DefineVariable(uint8_t global)
Definition: compile.cc:122
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
uint8_t ParseVariable(const char *errorMessage)
Definition: compile.cc:67
bool Match(TokenType type)
Definition: compile.cc:338
void uscript::Compiler::Variable ( bool  canAssign)
private

Definition at line 549 of file compile.cc.

549  {
550  NamedVariable(parser.previous, canAssign);
551 }
void NamedVariable(Token token, bool canAssign)
Definition: compile.cc:553
Parser parser
Definition: compile.h:50
void uscript::Compiler::WhileStatement ( )
private

Definition at line 183 of file compile.cc.

183  {
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 
193  Statement();
194 
195  PatchJump(exitJump);
197 
198  EmitLoop(loopStart);
199 }
void Expression()
Definition: compile.cc:394
void EmitByte(uint8_t byte)
Definition: compile.cc:359
void EmitLoop(int loopStart)
Definition: compile.cc:348
void Consume(TokenType type, const char *message)
Definition: compile.cc:409
int EmitJump(uint8_t instruction)
Definition: compile.cc:281
void PatchJump(int offset)
Definition: compile.cc:288
Chunk * CurrentChunk()
Definition: compile.h:124
std::vector< uint8_t > code
Definition: chunk.h:52
void Statement()
Definition: compile.cc:154

Member Data Documentation

Chunk* uscript::Compiler::current
private

Definition at line 52 of file compile.h.

std::vector<Local> uscript::Compiler::locals
private

Definition at line 53 of file compile.h.

Parser uscript::Compiler::parser
private

Definition at line 50 of file compile.h.

Scanner uscript::Compiler::scanner
private

Definition at line 51 of file compile.h.

int uscript::Compiler::scopeDepth
private

Definition at line 54 of file compile.h.

const char* uscript::Compiler::source
private

Definition at line 58 of file compile.h.

std::unordered_set<std::string> uscript::Compiler::strings
private

Definition at line 49 of file compile.h.

TClassList uscript::Compiler::tclasslist
private

Definition at line 56 of file compile.h.


The documentation for this class was generated from the following files: