[poincare] Units are now prefixed by "_" to distinct them from user

variable
This commit is contained in:
Émilie Feral
2020-01-20 14:31:49 +01:00
committed by Léa Saviot
parent 313430ec97
commit 489901a613
6 changed files with 67 additions and 47 deletions

View File

@@ -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[] = {

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -50,6 +50,7 @@ public:
Number,
BinaryNumber,
HexadecimalNumber,
Unit,
Identifier,
Undefined
};

View File

@@ -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

View File

@@ -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>