mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Units are now prefixed by "_" to distinct them from user
variable
This commit is contained in:
@@ -191,37 +191,37 @@ public:
|
||||
TimeRepresentatives[] = {
|
||||
Representative("s", nullptr,
|
||||
NegativeLongScalePrefixes, NegativeLongScalePrefixesCount),
|
||||
Representative("min", "60*s",
|
||||
Representative("min", "60*_s",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("h", "60*60*s",
|
||||
Representative("h", "60*60*_s",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("day", "24*60*60*s",
|
||||
Representative("day", "24*60*60*_s",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("week", "7*24*60*60*s",
|
||||
Representative("week", "7*24*60*60*_s",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("month", "30*7*24*60*60*s",
|
||||
Representative("month", "30*7*24*60*60*_s",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("year", "365.25*24*60*60*s",
|
||||
Representative("year", "365.25*24*60*60*_s",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
DistanceRepresentatives[] = {
|
||||
Representative("m", nullptr,
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
Representative("ang", "10^-10*m",
|
||||
Representative("ang", "10^-10*_m",
|
||||
NoPrefix, NoPrefixCount), //FIXME Codepoint
|
||||
Representative("au", "149587870700*m",
|
||||
Representative("au", "149587870700*_m",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("ly", "299792458*m/s*year",
|
||||
Representative("ly", "299792458*_m/_s*_year",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("pc", "180*60*60/π*au",
|
||||
Representative("pc", "180*60*60/π*_au",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
MassRepresentatives[] = {
|
||||
Representative("g", nullptr,
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
Representative("t", "1000kg",
|
||||
Representative("t", "1000_kg",
|
||||
PositiveLongScalePrefixes, PositiveLongScalePrefixesCount),
|
||||
Representative("Da", "(6.02214076*10^23*1000)^-1*kg",
|
||||
Representative("Da", "(6.02214076*10^23*1000)^-1*_kg",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
CurrentRepresentatives[] = {
|
||||
@@ -241,15 +241,15 @@ public:
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
FrequencyRepresentatives[] = {
|
||||
Representative("Hz", "s^-1",
|
||||
Representative("Hz", "_s^-1",
|
||||
PositiveLongScalePrefixes, PositiveLongScalePrefixesCount),
|
||||
},
|
||||
ForceRepresentatives[] = {
|
||||
Representative("N", "kg*m*s^-2",
|
||||
Representative("N", "_kg*_m*_s^-2",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
PressureRepresentatives[] = {
|
||||
Representative("Pa", "kg*m^-1*s^-2",
|
||||
Representative("Pa", "_kg*_m^-1*_s^-2",
|
||||
NoPrefix, NoPrefixCount),
|
||||
Representative("bar", "1000hPa",
|
||||
NoPrefix, NoPrefixCount),
|
||||
@@ -257,57 +257,57 @@ public:
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
EnergyRepresentatives[] = {
|
||||
Representative("J", "kg*m^2*s^-2",
|
||||
Representative("J", "_kg*_m^2*_s^-2",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
Representative("eV", "1.602176634*10^−19*J",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
PowerRepresentatives[] = {
|
||||
Representative("W", "kg*m^2*s^-3",
|
||||
Representative("W", "_kg*_m^2*_s^-3",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
ElectricChargeRepresentatives[] = {
|
||||
Representative("C", "A*s",
|
||||
Representative("C", "_A*_s",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
ElectricPotentialRepresentatives[] = {
|
||||
Representative("V", "kg*m^2*s^-3*A^-1",
|
||||
Representative("V", "_kg*_m^2*_s^-3*_A^-1",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
ElectricCapacitanceRepresentatives[] = {
|
||||
Representative("F", "A^2*s^4*kg^-1*m^-2",
|
||||
Representative("F", "_A^2*_s^4*_kg^-1*_m^-2",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
ElectricResistanceRepresentatives[] = {
|
||||
Representative("Ohm", "kg*m^2*s^-3*A^-2",
|
||||
Representative("Ohm", "_kg*_m^2*_s^-3*_A^-2",
|
||||
AllPrefixes, AllPrefixesCount), //FIXME Omega CodePoint?
|
||||
},
|
||||
ElectricConductanceRepresentatives[] = {
|
||||
Representative("S", "A^2*s^3*kg^-1*m^-2",
|
||||
Representative("S", "_A^2*_s^3*_kg^-1*_m^-2",
|
||||
AllPrefixes, AllPrefixesCount),
|
||||
},
|
||||
MagneticFluxRepresentatives[] = {
|
||||
Representative("Wb", "kg*m^2*s^-2*A^-1",
|
||||
Representative("Wb", "_kg*_m^2*_s^-2*_A^-1",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
MagneticFieldRepresentatives[] = {
|
||||
Representative("T", "kg*s^-2*A^-1",
|
||||
Representative("T", "_kg*_s^-2*_A^-1",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
InductanceRepresentatives[] = {
|
||||
Representative("H", "kg*m^2*s^-2*A^-2",
|
||||
Representative("H", "_kg*_m^2*_s^-2*_A^-2",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
CatalyticActivityRepresentatives[] = {
|
||||
Representative("kat", "mol*s^-1",
|
||||
Representative("kat", "_mol*_s^-1",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
SurfaceRepresentatives[] = {
|
||||
Representative("ha", "10^4*m^2",
|
||||
Representative("ha", "10^4*_m^2",
|
||||
NoPrefix, NoPrefixCount),
|
||||
},
|
||||
VolumeRepresentatives[] = {
|
||||
Representative("L", "10^-3*m^3",
|
||||
Representative("L", "10^-3*_m^3",
|
||||
NoPrefix, NoPrefixCount),
|
||||
};
|
||||
static constexpr const Dimension DimensionTable[] = {
|
||||
|
||||
@@ -18,12 +18,8 @@ Expression Parser::parse(Context * context) {
|
||||
}
|
||||
|
||||
bool Parser::IsReservedName(const char * name, size_t nameLength) {
|
||||
const Unit::Dimension * unitDimension = nullptr;
|
||||
const Unit::Representative * unitRepresentative = nullptr;
|
||||
const Unit::Prefix * unitPrefix = nullptr;
|
||||
return GetReservedFunction(name, nameLength) != nullptr
|
||||
|| IsSpecialIdentifierName(name, nameLength)
|
||||
|| Unit::CanParse(name, nameLength, &unitDimension, &unitRepresentative, &unitPrefix);
|
||||
|| IsSpecialIdentifierName(name, nameLength);
|
||||
}
|
||||
|
||||
// Private
|
||||
@@ -88,6 +84,7 @@ Expression Parser::parseUntil(Context * context, Token::Type stoppingType) {
|
||||
&Parser::parseNumber, // Token::Number
|
||||
&Parser::parseNumber, // Token::BinaryNumber
|
||||
&Parser::parseNumber, // Token::HexadecimalNumber
|
||||
&Parser::parseUnit, // Token::Unit
|
||||
&Parser::parseIdentifier, // Token::Identifier
|
||||
&Parser::parseUnexpected // Token::Undefined
|
||||
};
|
||||
@@ -134,13 +131,15 @@ bool Parser::nextTokenHasPrecedenceOver(Token::Type stoppingType) {
|
||||
|
||||
void Parser::isThereImplicitMultiplication() {
|
||||
/* This function is called at the end of
|
||||
* parseNumber, parseIdentifier, parseFactorial, parseMatrix, parseLeftParenthesis
|
||||
* in order to check whether it should be followed by a Token::ImplicitTimes.
|
||||
* parseNumber, parseIdentifier, parseUnit, parseFactorial, parseMatrix,
|
||||
* parseLeftParenthesis in order to check whether it should be followed by a
|
||||
* Token::ImplicitTimes.
|
||||
* In that case, m_pendingImplicitMultiplication is set to true,
|
||||
* so that popToken, popTokenIfType, nextTokenHasPrecedenceOver can handle implicit multiplication. */
|
||||
m_pendingImplicitMultiplication = (
|
||||
m_nextToken.is(Token::Number) ||
|
||||
m_nextToken.is(Token::Constant) ||
|
||||
m_nextToken.is(Token::Unit) ||
|
||||
m_nextToken.is(Token::Identifier) ||
|
||||
m_nextToken.is(Token::LeftParenthesis) ||
|
||||
m_nextToken.is(Token::LeftSystemParenthesis) ||
|
||||
@@ -336,10 +335,27 @@ void Parser::parseBang(Context * context, Expression & leftHandSide, Token::Type
|
||||
}
|
||||
|
||||
void Parser::parseConstant(Context * context, Expression & leftHandSide, Token::Type stoppingType) {
|
||||
assert(leftHandSide.isUninitialized());
|
||||
leftHandSide = Constant::Builder(m_currentToken.codePoint());
|
||||
isThereImplicitMultiplication();
|
||||
}
|
||||
|
||||
void Parser::parseUnit(Context * context, Expression & leftHandSide, Token::Type stoppingType) {
|
||||
assert(leftHandSide.isUninitialized());
|
||||
const Unit::Dimension * unitDimension = nullptr;
|
||||
const Unit::Representative * unitRepresentative = nullptr;
|
||||
const Unit::Prefix * unitPrefix = nullptr; leftHandSide = Constant::Builder(m_currentToken.codePoint());
|
||||
if (Unit::CanParse(m_currentToken.text(), m_currentToken.length(),
|
||||
&unitDimension, &unitRepresentative, &unitPrefix))
|
||||
{
|
||||
leftHandSide = Unit::Builder(unitDimension, unitRepresentative, unitPrefix);
|
||||
} else {
|
||||
m_status = Status::Error; // Unit does not exist
|
||||
return;
|
||||
}
|
||||
isThereImplicitMultiplication();
|
||||
}
|
||||
|
||||
void Parser::parseReservedFunction(Context * context, Expression & leftHandSide, const Expression::FunctionHelper * const * functionHelper) {
|
||||
const char * name = (**functionHelper).name();
|
||||
Expression parameters = parseFunctionParameters(context);
|
||||
@@ -477,22 +493,12 @@ void Parser::parseCustomIdentifier(Context * context, Expression & leftHandSide,
|
||||
}
|
||||
|
||||
void Parser::parseIdentifier(Context * context, Expression & leftHandSide, Token::Type stoppingType) {
|
||||
if (!leftHandSide.isUninitialized()) {
|
||||
m_status = Status::Error; //FIXME
|
||||
return;
|
||||
}
|
||||
assert(leftHandSide.isUninitialized());
|
||||
const Expression::FunctionHelper * const * functionHelper = GetReservedFunction(m_currentToken.text(), m_currentToken.length());
|
||||
const Unit::Dimension * unitDimension = nullptr;
|
||||
const Unit::Representative * unitRepresentative = nullptr;
|
||||
const Unit::Prefix * unitPrefix = nullptr;
|
||||
if (functionHelper != nullptr) {
|
||||
parseReservedFunction(context, leftHandSide, functionHelper);
|
||||
} else if (IsSpecialIdentifierName(m_currentToken.text(), m_currentToken.length())) {
|
||||
parseSpecialIdentifier(context, leftHandSide);
|
||||
} else if (Unit::CanParse(m_currentToken.text(), m_currentToken.length(),
|
||||
&unitDimension, &unitRepresentative, &unitPrefix))
|
||||
{
|
||||
leftHandSide = Unit::Builder(unitDimension, unitRepresentative, unitPrefix);
|
||||
} else {
|
||||
parseCustomIdentifier(context, leftHandSide, m_currentToken.text(), m_currentToken.length(), false);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ private:
|
||||
void parseUnexpected(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
void parseNumber(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
void parseConstant(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
void parseUnit(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
void parseIdentifier(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
void parseEmpty(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
void parseMatrix(Context * context, Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
Number,
|
||||
BinaryNumber,
|
||||
HexadecimalNumber,
|
||||
Unit,
|
||||
Identifier,
|
||||
Undefined
|
||||
};
|
||||
|
||||
@@ -147,6 +147,11 @@ Token Tokenizer::popToken() {
|
||||
if (!nextCodePointIsNeitherDotNorDigit) {
|
||||
return popNumber();
|
||||
}
|
||||
if (c == '_') {
|
||||
Token result(Token::Unit);
|
||||
result.setString(start + 1, popIdentifier());
|
||||
return result;
|
||||
}
|
||||
if (isLetter(c)) {
|
||||
Token result(Token::Identifier);
|
||||
result.setString(start, 1 + popIdentifier()); // We already popped 1 code point
|
||||
|
||||
@@ -83,6 +83,9 @@ int UnitNode::simplificationOrderSameType(const ExpressionNode * e, bool ascendi
|
||||
}
|
||||
|
||||
Layout UnitNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
/* TODO: compute the bufferSize more precisely... So far the longest unit is
|
||||
* "month" of size 6 but later, we might add unicode to represent ohm or µ
|
||||
* which would change the required size?*/
|
||||
static constexpr size_t bufferSize = 10;
|
||||
char buffer[bufferSize];
|
||||
int length = serialize(buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits);
|
||||
@@ -91,7 +94,11 @@ Layout UnitNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int
|
||||
}
|
||||
|
||||
int UnitNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return m_representative->serialize(buffer, bufferSize, m_prefix);
|
||||
assert(bufferSize >= 0);
|
||||
int underscoreLength = minInt(strlcpy(buffer, "_", bufferSize), bufferSize - 1);
|
||||
buffer += underscoreLength;
|
||||
bufferSize -= underscoreLength;
|
||||
return underscoreLength + m_representative->serialize(buffer, bufferSize, m_prefix);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
Reference in New Issue
Block a user