OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4AulCompiler::ConstexprEvaluator Class Reference
Inheritance diagram for C4AulCompiler::ConstexprEvaluator:
[legend]
Collaboration diagram for C4AulCompiler::ConstexprEvaluator:
[legend]

Classes

class  ExpressionNotConstant
 

Public Types

enum  EvalFlag { IgnoreUnset = 1<<0, SuppressErrors = 1<<1 }
 
typedef int EvalFlags
 

Public Member Functions

void visit (const ::aul::ast::StringLit *n) override
 
void visit (const ::aul::ast::IntLit *n) override
 
void visit (const ::aul::ast::BoolLit *n) override
 
void visit (const ::aul::ast::ArrayLit *n) override
 
void visit (const ::aul::ast::ProplistLit *n) override
 
void visit (const ::aul::ast::NilLit *) override
 
void visit (const ::aul::ast::ThisLit *n) override
 
void visit (const ::aul::ast::VarExpr *n) override
 
void visit (const ::aul::ast::UnOpExpr *n) override
 
void visit (const ::aul::ast::BinOpExpr *n) override
 
void visit (const ::aul::ast::AssignmentExpr *n) override
 
void visit (const ::aul::ast::SubscriptExpr *n) override
 
void visit (const ::aul::ast::SliceExpr *n) override
 
void visit (const ::aul::ast::CallExpr *n) override
 
void visit (const ::aul::ast::FunctionExpr *n) override
 
virtual void visit (const ::aul::ast::Noop *)
 
virtual void visit (const ::aul::ast::ParExpr *)
 
virtual void visit (const ::aul::ast::Block *)
 
virtual void visit (const ::aul::ast::Return *)
 
virtual void visit (const ::aul::ast::ForLoop *)
 
virtual void visit (const ::aul::ast::RangeLoop *)
 
virtual void visit (const ::aul::ast::DoLoop *)
 
virtual void visit (const ::aul::ast::WhileLoop *)
 
virtual void visit (const ::aul::ast::Break *)
 
virtual void visit (const ::aul::ast::Continue *)
 
virtual void visit (const ::aul::ast::If *)
 
virtual void visit (const ::aul::ast::VarDecl *)
 
virtual void visit (const ::aul::ast::FunctionDecl *)
 
virtual void visit (const ::aul::ast::IncludePragma *)
 
virtual void visit (const ::aul::ast::AppendtoPragma *)
 
virtual void visit (const ::aul::ast::Script *)
 
template<class T >
void visit (const T *)=delete
 

Static Public Member Functions

static C4Value eval (C4ScriptHost *host, const ::aul::ast::Expr *e, EvalFlags flags=0)
 
static C4Value eval_static (C4ScriptHost *host, C4PropListStatic *parent, const std::string &parent_key, const ::aul::ast::Expr *e, EvalFlags flags=0)
 

Detailed Description

Definition at line 303 of file C4AulCompiler.cpp.

Member Typedef Documentation

Definition at line 317 of file C4AulCompiler.cpp.

Member Enumeration Documentation

Enumerator
IgnoreUnset 
SuppressErrors 

Definition at line 306 of file C4AulCompiler.cpp.

307  {
308  // If this flag is set, ConstexprEvaluator will assume unset values
309  // are nil. If it is not set, evaluation of unset values will send an
310  // ExpressionNotConstant to the error handler.
311  IgnoreUnset = 1<<0,
312  // If this flag is set, ConstexprEvaluator will not send exceptions to
313  // the error handler (so it doesn't report them twice: once from the
314  // preparsing step, then again from the compile step).
315  SuppressErrors = 1<<1
316  };

Member Function Documentation

C4Value C4AulCompiler::ConstexprEvaluator::eval ( C4ScriptHost host,
const ::aul::ast::Expr e,
EvalFlags  flags = 0 
)
static

Definition at line 1708 of file C4AulCompiler.cpp.

References C4VNull, C4ScriptHost::Engine, C4AulScriptEngine::ErrorHandler, C4AulErrorHandler::OnError(), and C4AulError::what().

1709 {
1710  ConstexprEvaluator ce(host);
1711  ce.ignore_unset_values = (flags & IgnoreUnset) == IgnoreUnset;
1712  try
1713  {
1714  e->accept(&ce);
1715  return ce.v;
1716  }
1717  catch (C4AulParseError &e)
1718  {
1719  if ((flags & SuppressErrors) == 0)
1720  host->Engine->ErrorHandler->OnError(e.what());
1721  return C4VNull;
1722  }
1723 }
C4AulScriptEngine * Engine
Definition: C4ScriptHost.h:76
const char * what() const noexceptoverride
virtual void OnError(const char *msg)=0
const C4Value C4VNull
Definition: C4Value.cpp:30
virtual void accept(::aul::AstVisitor *) const =0
C4AulErrorHandler * ErrorHandler
Definition: C4Aul.h:128

Here is the call graph for this function:

C4Value C4AulCompiler::ConstexprEvaluator::eval_static ( C4ScriptHost host,
C4PropListStatic parent,
const std::string &  parent_key,
const ::aul::ast::Expr e,
EvalFlags  flags = 0 
)
static

Definition at line 1725 of file C4AulCompiler.cpp.

References C4VNull, C4ScriptHost::Engine, C4AulScriptEngine::ErrorHandler, C4AulErrorHandler::OnError(), and C4AulError::what().

Referenced by C4AulCompiler::ConstantResolver::visit().

1726 {
1727  ConstexprEvaluator ce(host);
1728  ce.proplist_magic = ConstexprEvaluator::ProplistMagic{ true, parent, parent_key };
1729  ce.ignore_unset_values = (flags & IgnoreUnset) == IgnoreUnset;
1730  try
1731  {
1732  e->accept(&ce);
1733  return ce.v;
1734  }
1735  catch (C4AulParseError &e)
1736  {
1737  if ((flags & SuppressErrors) == 0)
1738  host->Engine->ErrorHandler->OnError(e.what());
1739  return C4VNull;
1740  }
1741 }
C4AulScriptEngine * Engine
Definition: C4ScriptHost.h:76
const char * what() const noexceptoverride
virtual void OnError(const char *msg)=0
const C4Value C4VNull
Definition: C4Value.cpp:30
virtual void accept(::aul::AstVisitor *) const =0
C4AulErrorHandler * ErrorHandler
Definition: C4Aul.h:128

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void aul::AstVisitor::visit ( const ::aul::ast::Noop )
inlinevirtualinherited

Reimplemented in C4AulCompiler::CodegenAstVisitor.

Definition at line 63 of file C4AulAST.h.

63 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::ParExpr )
inlinevirtualinherited
virtual void aul::AstVisitor::visit ( const ::aul::ast::Block )
inlinevirtualinherited

Reimplemented in aul::DefaultRecursiveVisitor, and C4AulCompiler::CodegenAstVisitor.

Definition at line 79 of file C4AulAST.h.

79 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::Return )
inlinevirtualinherited

Reimplemented in aul::DefaultRecursiveVisitor, and C4AulCompiler::CodegenAstVisitor.

Definition at line 80 of file C4AulAST.h.

80 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::ForLoop )
inlinevirtualinherited

Reimplemented in aul::DefaultRecursiveVisitor, and C4AulCompiler::CodegenAstVisitor.

Definition at line 81 of file C4AulAST.h.

81 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::RangeLoop )
inlinevirtualinherited
virtual void aul::AstVisitor::visit ( const ::aul::ast::DoLoop )
inlinevirtualinherited

Reimplemented in aul::DefaultRecursiveVisitor, and C4AulCompiler::CodegenAstVisitor.

Definition at line 83 of file C4AulAST.h.

83 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::WhileLoop )
inlinevirtualinherited

Reimplemented in aul::DefaultRecursiveVisitor, and C4AulCompiler::CodegenAstVisitor.

Definition at line 84 of file C4AulAST.h.

84 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::Break )
inlinevirtualinherited

Reimplemented in C4AulCompiler::CodegenAstVisitor.

Definition at line 85 of file C4AulAST.h.

85 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::Continue )
inlinevirtualinherited

Reimplemented in C4AulCompiler::CodegenAstVisitor.

Definition at line 86 of file C4AulAST.h.

86 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::If )
inlinevirtualinherited

Reimplemented in aul::DefaultRecursiveVisitor, and C4AulCompiler::CodegenAstVisitor.

Definition at line 87 of file C4AulAST.h.

87 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::VarDecl )
inlinevirtualinherited
virtual void aul::AstVisitor::visit ( const ::aul::ast::FunctionDecl )
inlinevirtualinherited
virtual void aul::AstVisitor::visit ( const ::aul::ast::IncludePragma )
inlinevirtualinherited

Reimplemented in C4AulCompiler::PreparseAstVisitor.

Definition at line 91 of file C4AulAST.h.

91 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::AppendtoPragma )
inlinevirtualinherited

Reimplemented in C4AulCompiler::PreparseAstVisitor.

Definition at line 92 of file C4AulAST.h.

92 {}
virtual void aul::AstVisitor::visit ( const ::aul::ast::Script )
inlinevirtualinherited
template<class T >
void aul::AstVisitor::visit ( const T *  )
deleteinherited
void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::StringLit n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1743 of file C4AulCompiler.cpp.

References C4VString().

1743 { v = C4VString(n->value.c_str()); }
std::string value
Definition: C4AulAST.h:157
C4Value C4VString(C4String *pStr)
Definition: C4Value.h:246

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::IntLit n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1745 of file C4AulCompiler.cpp.

References C4VInt().

1745 { v = C4VInt(n->value); }
C4Value C4VInt(int32_t i)
Definition: C4Value.h:242
uint32_t value
Definition: C4AulAST.h:165

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::BoolLit n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1747 of file C4AulCompiler.cpp.

References C4VBool().

1747 { v = C4VBool(n->value); }
C4Value C4VBool(bool b)
Definition: C4Value.h:243

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::ArrayLit n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1749 of file C4AulCompiler.cpp.

References a, and C4VArray().

1750 {
1751  auto a = std::make_unique<C4ValueArray>(n->values.size());
1752  for (size_t i = 0; i < n->values.size(); ++i)
1753  {
1754  n->values[i]->accept(this);
1755  a->SetItem(i, v);
1756  }
1757  v = C4VArray(a.release());
1758 }
#define a
std::vector< ExprPtr > values
Definition: C4AulAST.h:180
C4Value C4VArray(C4ValueArray *pArray)
Definition: C4Value.h:249

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::ProplistLit n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1760 of file C4AulCompiler.cpp.

References C4VNull, C4VPropList(), C4ScriptHost::Engine, C4String::GetCStr(), C4AulScriptEngine::GetGlobalConstant(), C4Value::getPropList(), C4PropList::IsStatic(), C4PropList::New(), C4PropList::NewStatic(), C4StringTable::RegString(), C4PropList::SetPropertyByS(), and Strings.

1761 {
1762  std::unique_ptr<C4PropList> new_proplist;
1763  C4PropList *p = nullptr;
1764 
1765  bool first_pass = true;
1766 
1767  if (proplist_magic.active)
1768  {
1769  // Check if there's already a proplist available
1770  C4String *key = ::Strings.RegString(proplist_magic.key.c_str());
1771  C4Value old;
1772  if (proplist_magic.parent)
1773  {
1774  proplist_magic.parent->GetPropertyByS(key, &old);
1775  }
1776  else
1777  {
1778  // If proplist_magic.parent is nullptr, we're handling a global constant.
1779  host->Engine->GetGlobalConstant(key->GetCStr(), &old);
1780  }
1781  if (old.getPropList())
1782  {
1783  p = old.getPropList();
1784  first_pass = false;
1785  }
1786  else
1787  {
1788  p = C4PropList::NewStatic(nullptr, proplist_magic.parent, key);
1789  new_proplist.reset(p);
1790  }
1791  }
1792  else
1793  {
1794  p = C4PropList::New();
1795  new_proplist.reset(p);
1796  }
1797 
1798  // Since the values may be functions that refer to other values in the
1799  // proplist, pre-populate the new proplist with dummy values until the
1800  // real ones are set
1801  if (first_pass)
1802  {
1803  for (const auto &kv : n->values)
1804  {
1805  p->SetPropertyByS(::Strings.RegString(kv.first.c_str()), C4VNull);
1806  }
1807  }
1808 
1809  auto saved_magic = std::move(proplist_magic);
1810  for (const auto &kv : n->values)
1811  {
1812  proplist_magic = ProplistMagic { saved_magic.active, p->IsStatic(), kv.first };
1813  kv.second->accept(this);
1814  p->SetPropertyByS(::Strings.RegString(kv.first.c_str()), v);
1815  }
1816  proplist_magic = std::move(saved_magic);
1817  v = C4VPropList(p);
1818  new_proplist.release();
1819 }
const char * GetCStr() const
Definition: C4StringTable.h:49
C4String * RegString(StdStrBuf String)
bool GetGlobalConstant(const char *szName, C4Value *pTargetValue)
virtual class C4PropListStatic * IsStatic()
Definition: C4PropList.h:85
C4AulScriptEngine * Engine
Definition: C4ScriptHost.h:76
C4StringTable Strings
Definition: C4Globals.cpp:42
C4Value C4VPropList(C4PropList *p)
Definition: C4Value.h:245
static C4PropListStatic * NewStatic(C4PropList *prototype, const C4PropListStatic *parent, C4String *key)
Definition: C4PropList.cpp:70
const C4Value C4VNull
Definition: C4Value.cpp:30
virtual void SetPropertyByS(C4String *k, const C4Value &to)
Definition: C4PropList.cpp:952
std::vector< std::pair< std::string, ExprPtr > > values
Definition: C4AulAST.h:187
static C4PropList * New(C4PropList *prototype=nullptr)
Definition: C4PropList.cpp:64
C4PropList * getPropList() const
Definition: C4Value.h:116

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::NilLit )
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1821 of file C4AulCompiler.cpp.

References C4VNull.

1821 { v = C4VNull; }
const C4Value C4VNull
Definition: C4Value.cpp:30
void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::ThisLit n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1823 of file C4AulCompiler.cpp.

1823 { nonconst(n, "\"this\" is not a global constant"); }
void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::VarExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1825 of file C4AulCompiler.cpp.

References C4VNull, C4ScriptHost::Engine, C4StringTable::FindString(), C4AulScriptEngine::GetGlobalConstant(), C4PropList::GetPropertyByS(), C4ScriptHost::GetPropList(), and Strings.

1826 {
1827  const char *cname = n->identifier.c_str();
1828  C4String *interned = ::Strings.FindString(cname);
1829  if (interned && host->GetPropList()->GetPropertyByS(interned, &v))
1830  return;
1831  if (host->Engine->GetGlobalConstant(cname, &v))
1832  return;
1833 
1834  if (ignore_unset_values)
1835  {
1836  v = C4VNull;
1837  return;
1838  }
1839 
1840  nonconst(n, "the variable \"%s\" is not a global constant", cname);
1841 }
C4String * FindString(const char *strString) const
bool GetGlobalConstant(const char *szName, C4Value *pTargetValue)
C4AulScriptEngine * Engine
Definition: C4ScriptHost.h:76
virtual C4PropListStatic * GetPropList()
Definition: C4ScriptHost.h:50
C4StringTable Strings
Definition: C4Globals.cpp:42
virtual bool GetPropertyByS(const C4String *k, C4Value *pResult) const
Definition: C4PropList.cpp:757
const C4Value C4VNull
Definition: C4Value.cpp:30
std::string identifier
Definition: C4AulAST.h:205

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::UnOpExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1843 of file C4AulCompiler.cpp.

References C4Value::_getInt(), AB_BitNot, AB_Neg, AB_Not, C4ScriptOpMap, C4Value::getBool(), C4Value::SetBool(), and C4Value::SetInt().

1844 {
1845  n->operand->accept(this);
1846  assert(n->op > 0);
1847  const auto &op = C4ScriptOpMap[n->op];
1848  if (op.Changer)
1849  nonconst(n, "unary operator %s is applied in a non-const fashion", op.Identifier);
1850  AssertValueType(v, op.Type1, op.Identifier, n);
1851  switch (op.Code)
1852  {
1853  case AB_BitNot:
1854  v.SetInt(~v._getInt());
1855  break;
1856  case AB_Not:
1857  v.SetBool(!v.getBool());
1858  break;
1859  case AB_Neg:
1860  v.SetInt(-v._getInt());
1861  break;
1862  default:
1863  assert(!"ConstexprEvaluator: Unexpected unary operator");
1864  throw Error(host, host, n, nullptr, "internal error: unary operator not found in operator table");
1865  }
1866 }
const C4ScriptOpDef C4ScriptOpMap[]
Definition: C4AulParse.cpp:261
void SetBool(bool b)
Definition: C4Value.h:137
bool getBool() const
Definition: C4Value.h:113
int32_t _getInt() const
Definition: C4Value.h:122
void SetInt(int32_t i)
Definition: C4Value.h:136

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::BinOpExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1868 of file C4AulCompiler.cpp.

References C4Value::_getInt(), AB_BitAnd, AB_BitOr, AB_BitXOr, AB_Div, AB_Equal, AB_GreaterThan, AB_GreaterThanEqual, AB_JUMPAND, AB_JUMPNNIL, AB_JUMPOR, AB_LeftShift, AB_LessThan, AB_LessThanEqual, AB_Mod, AB_Mul, AB_NotEqual, AB_Pow, AB_RightShift, AB_Sub, AB_Sum, BOOL_BINOP, C4ScriptOpMap, C4V_Nil, ENSURE_COND, C4Value::GetType(), INT_BINOP, C4Value::IsIdenticalTo(), Pow(), C4Value::SetBool(), and C4Value::SetInt().

1869 {
1870  assert(n->op > 0);
1871  const auto &op = C4ScriptOpMap[n->op];
1872  if (op.Changer)
1873  nonconst(n, "binary operator %s is applied in a non-const fashion", op.Identifier);
1874 
1875  n->lhs->accept(this);
1876  C4Value lhs = v;
1877  // Evaluate the short-circuiting operators here
1878  if ((op.Code == AB_JUMPAND && !lhs) || (op.Code == AB_JUMPOR && lhs) || (op.Code == AB_JUMPNNIL && lhs.GetType() != C4V_Nil))
1879  {
1880  v = lhs;
1881  return;
1882  }
1883  n->rhs->accept(this);
1884  C4Value &rhs = v;
1885 
1886  AssertValueType(lhs, op.Type1, op.Identifier, n);
1887  AssertValueType(rhs, op.Type2, op.Identifier, n);
1888 
1889  switch (op.Code)
1890  {
1891  case AB_Pow:
1892  v.SetInt(Pow(lhs._getInt(), rhs._getInt()));
1893  break;
1894  case AB_Div:
1895  ENSURE_COND(rhs._getInt() != 0, "division by zero");
1896  ENSURE_COND(lhs._getInt() != INT32_MIN || rhs._getInt() != -1, "division overflow");
1897  v.SetInt(lhs._getInt() / rhs._getInt());
1898  break;
1899  case AB_Mul:
1900  v.SetInt(lhs._getInt() * rhs._getInt());
1901  break;
1902  case AB_Mod:
1903  ENSURE_COND(rhs._getInt() != 0, "division by zero");
1904  ENSURE_COND(lhs._getInt() != INT32_MIN || rhs._getInt() != -1, "division overflow");
1905  v.SetInt(lhs._getInt() / rhs._getInt());
1906  break;
1907 #define INT_BINOP(code, op) case code: v.SetInt(lhs._getInt() op rhs._getInt()); break
1908  INT_BINOP(AB_Sum, +);
1909  INT_BINOP(AB_Sub, -);
1910  INT_BINOP(AB_LeftShift, << );
1911  INT_BINOP(AB_RightShift, >> );
1912  INT_BINOP(AB_BitAnd, &);
1913  INT_BINOP(AB_BitXOr, ^);
1914  INT_BINOP(AB_BitOr, | );
1915 #undef INT_BINOP
1916 #define BOOL_BINOP(code, op) case code: v.SetBool(lhs._getInt() op rhs._getInt()); break
1917  BOOL_BINOP(AB_LessThan, <);
1921 #undef BOOL_BINOP
1922  case AB_Equal:
1923  v.SetBool(lhs.IsIdenticalTo(rhs));
1924  break;
1925  case AB_NotEqual:
1926  v.SetBool(!lhs.IsIdenticalTo(rhs));
1927  break;
1928  case AB_JUMPAND:
1929  case AB_JUMPOR:
1930  case AB_JUMPNNIL:
1931  // If we hit this, then the short-circuit above failed
1932  v = rhs;
1933  break;
1934  default:
1935  assert(!"ConstexprEvaluator: Unexpected binary operator");
1936  throw Error(host, host, n, nullptr, "internal error: binary operator not found in operator table");
1937  break;
1938  }
1939 }
const C4ScriptOpDef C4ScriptOpMap[]
Definition: C4AulParse.cpp:261
#define BOOL_BINOP(code, op)
void SetBool(bool b)
Definition: C4Value.h:137
#define ENSURE_COND(cond, failmsg)
C4V_Type GetType() const
Definition: C4Value.h:161
int32_t _getInt() const
Definition: C4Value.h:122
void SetInt(int32_t i)
Definition: C4Value.h:136
int Pow(int base, int exponent)
Definition: Standard.cpp:69
bool IsIdenticalTo(const C4Value &cmp) const
Definition: C4Value.h:149
#define INT_BINOP(code, op)

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::AssignmentExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1941 of file C4AulCompiler.cpp.

1942 {
1943  nonconst(n, "updating assignment used in a non-const fashion");
1944 }
void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::SubscriptExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1946 of file C4AulCompiler.cpp.

References C4V_Array, C4V_Int, C4V_PropList, C4V_String, C4Value::CheckConversion(), ENSURE_COND, FormatString(), C4Value::getArray(), C4Value::getInt(), C4ValueArray::GetItem(), C4PropList::GetPropertyByS(), C4Value::getPropList(), C4Value::getStr(), C4Value::GetTypeName(), and C4Value::Set0().

1947 {
1948  n->object->accept(this);
1949  C4Value obj = v;
1950  n->index->accept(this);
1951  C4Value &index = v;
1952 
1953  if (obj.CheckConversion(C4V_Array))
1954  {
1955  ENSURE_COND(index.CheckConversion(C4V_Int), FormatString("array access: index of type %s, but expected int", index.GetTypeName()).getData());
1956  v = obj.getArray()->GetItem(index.getInt());
1957  }
1958  else if (obj.CheckConversion(C4V_PropList))
1959  {
1960  ENSURE_COND(index.CheckConversion(C4V_String), FormatString("proplist access: index of type %s, but expected string", index.GetTypeName()).getData());
1961  if (!obj.getPropList()->GetPropertyByS(index.getStr(), &v))
1962  v.Set0();
1963  }
1964  else
1965  {
1966  ENSURE_COND(false, FormatString("can't access %s as array or proplist", obj.GetTypeName()).getData());
1967  }
1968 }
C4String * getStr() const
Definition: C4Value.h:117
#define ENSURE_COND(cond, failmsg)
const C4Value & GetItem(int32_t iElem) const
Definition: C4ValueArray.h:38
ALWAYS_INLINE bool CheckConversion(C4V_Type vtToType) const
Definition: C4Value.h:189
const char * GetTypeName() const
Definition: C4Value.h:164
virtual bool GetPropertyByS(const C4String *k, C4Value *pResult) const
Definition: C4PropList.cpp:757
C4ValueArray * getArray() const
Definition: C4Value.h:118
int32_t getInt() const
Definition: C4Value.h:112
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
C4PropList * getPropList() const
Definition: C4Value.h:116

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::SliceExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1970 of file C4AulCompiler.cpp.

References C4V_Array, C4V_Int, C4Value::CheckConversion(), ENSURE_COND, FormatString(), C4Value::getArray(), C4Value::getInt(), C4ValueArray::GetSlice(), C4Value::GetTypeName(), and C4Value::SetArray().

1971 {
1972  n->object->accept(this);
1973  C4Value obj = v;
1974  n->start->accept(this);
1975  C4Value start = v;
1976  n->end->accept(this);
1977  C4Value &end = v;
1978 
1979  ENSURE_COND(obj.CheckConversion(C4V_Array), FormatString("array slice: can't access %s as an array", obj.GetTypeName()).getData());
1980  ENSURE_COND(start.CheckConversion(C4V_Int), FormatString("array slice: start index of type %s, int expected", start.GetTypeName()).getData());
1981  ENSURE_COND(end.CheckConversion(C4V_Int), FormatString("array slice: end index of type %s, int expected", end.GetTypeName()).getData());
1982 
1983  v.SetArray(obj.getArray()->GetSlice(start.getInt(), end.getInt()));
1984 }
#define ENSURE_COND(cond, failmsg)
ALWAYS_INLINE bool CheckConversion(C4V_Type vtToType) const
Definition: C4Value.h:189
const char * GetTypeName() const
Definition: C4Value.h:164
void SetArray(C4ValueArray *Array)
Definition: C4Value.h:139
C4ValueArray * getArray() const
Definition: C4Value.h:118
int32_t getInt() const
Definition: C4Value.h:112
C4ValueArray * GetSlice(int32_t startIndex, int32_t endIndex)
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270

Here is the call graph for this function:

void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::CallExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1986 of file C4AulCompiler.cpp.

1987 {
1988  // TODO: allow side-effect-free calls here
1989  nonconst(n, "call to function (%s) not supported in constant expressions", n->callee.c_str());
1990 }
std::string callee
Definition: C4AulAST.h:258
void C4AulCompiler::ConstexprEvaluator::visit ( const ::aul::ast::FunctionExpr n)
overridevirtual

Reimplemented from aul::AstVisitor.

Definition at line 1992 of file C4AulCompiler.cpp.

References C4AulScriptFunc::AddPar(), C4AUL_MAX_Par, C4AulCompiler::CodegenAstVisitor::EmitFunctionCode(), ENSURE_COND, C4AulScriptFunc::ParCount, C4Value::SetFunction(), C4AulScriptFunc::SFunc(), and C4AulCompiler::PreparseAstVisitor::visit().

1993 {
1994  // Function expressions can only occur inside static proplists.
1995  ENSURE_COND(proplist_magic.active, "internal error: function expression outside of static proplist");
1996 
1997  C4AulScriptFunc *sfunc = nullptr;
1998  bool first_pass = true;
1999 
2000  if (auto func = proplist_magic.parent->GetFunc(proplist_magic.key.c_str()))
2001  {
2002  sfunc = func->SFunc();
2003  first_pass = false;
2004  }
2005  else
2006  {
2007  sfunc = new C4AulScriptFunc(proplist_magic.parent, host, proplist_magic.key.c_str(), n->loc);
2008  }
2009 
2010  ENSURE_COND(sfunc != nullptr, "internal error: function expression target resolved to non-function value");
2011 
2012  if (first_pass)
2013  {
2014  for (const auto &param : n->params)
2015  {
2016  sfunc->AddPar(param.name.c_str());
2017  }
2018  if (n->has_unnamed_params)
2019  sfunc->ParCount = C4AUL_MAX_Par;
2020 
2021  PreparseAstVisitor preparser(host, host, sfunc);
2022  preparser.visit(n->body.get());
2023  }
2024  else
2025  {
2026  CodegenAstVisitor cg(sfunc);
2027  cg.EmitFunctionCode(n);
2028  }
2029 
2030  v.SetFunction(sfunc);
2031 }
#define ENSURE_COND(cond, failmsg)
std::vector< Parameter > params
Definition: C4AulAST.h:377
std::unique_ptr< Block > body
Definition: C4AulAST.h:379
#define C4AUL_MAX_Par
Definition: C4AulFunc.h:26
bool has_unnamed_params
Definition: C4AulAST.h:378
C4AulScriptFunc * SFunc() override
void AddPar(const char *Idtf, C4V_Type type=C4V_Any)
void SetFunction(C4AulFunc *Fn)
Definition: C4Value.h:140
const char * loc
Definition: C4AulAST.h:123

Here is the call graph for this function:


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