build: remove most of MathRules.

We shouldn't be doing these crazy things.

The only usage of this is the NextID rule which computes an unique
number by incrementing a variable. This is used for example to generate
names for the extra files used in xattr emulation.

But we certainly don't need multiplication, division, etc. That's better
done in scripts (Python, for example) in rule actions. So keep just
enough of this for NextID to work, and we could probably make it even
simpler.

Change-Id: Id06d4f5e236205203fe8d604de440753b63801bc
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6088
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Tested-by: Automation <automation@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2023-02-25 14:40:49 +01:00 committed by waddlesplash
parent e70df3f778
commit dd8d24ee62

View File

@ -1,8 +1,5 @@
# Rules providing basic arithmetic operations
HAIKU_ZERO = + 0 ;
HAIKU_ONE = + 1 ;
HAIKU_PAD_9 = 0 1 2 3 4 5 6 7 8 ;
# a > b <==> $(HAIKU_DIGIT_GREATER_$(a)[1$(b)])
@ -29,157 +26,8 @@ HAIKU_DIGIT_ADD_7 = $(HAIKU_PAD_9) 7 8 9 0 1 2 3 4 5 6 ;
HAIKU_DIGIT_ADD_8 = $(HAIKU_PAD_9) 8 9 0 1 2 3 4 5 6 7 ;
HAIKU_DIGIT_ADD_9 = $(HAIKU_PAD_9) 9 0 1 2 3 4 5 6 7 8 ;
# a - b == $(HAIKU_DIGIT_SUB_$(a)[1$(b)]) (carry ignored)
HAIKU_DIGIT_SUB_0 = $(HAIKU_PAD_9) 0 9 8 7 6 5 4 3 2 1 ;
HAIKU_DIGIT_SUB_1 = $(HAIKU_PAD_9) 1 0 9 8 7 6 5 4 3 2 ;
HAIKU_DIGIT_SUB_2 = $(HAIKU_PAD_9) 2 1 0 9 8 7 6 5 4 3 ;
HAIKU_DIGIT_SUB_3 = $(HAIKU_PAD_9) 3 2 1 0 9 8 7 6 5 4 ;
HAIKU_DIGIT_SUB_4 = $(HAIKU_PAD_9) 4 3 2 1 0 9 8 7 6 5 ;
HAIKU_DIGIT_SUB_5 = $(HAIKU_PAD_9) 5 4 3 2 1 0 9 8 7 6 ;
HAIKU_DIGIT_SUB_6 = $(HAIKU_PAD_9) 6 5 4 3 2 1 0 9 8 7 ;
HAIKU_DIGIT_SUB_7 = $(HAIKU_PAD_9) 7 6 5 4 3 2 1 0 9 8 ;
HAIKU_DIGIT_SUB_8 = $(HAIKU_PAD_9) 8 7 6 5 4 3 2 1 0 9 ;
HAIKU_DIGIT_SUB_9 = $(HAIKU_PAD_9) 9 8 7 6 5 4 3 2 1 0 ;
# a * b == $(HAIKU_DIGIT_MULT_CARRY_$(a)[1$(b)]) $(HAIKU_DIGIT_MULT_$(a)[1$(b)])
HAIKU_DIGIT_MULT_0 = $(HAIKU_PAD_9) 0 0 0 0 0 0 0 0 0 0 ;
HAIKU_DIGIT_MULT_1 = $(HAIKU_PAD_9) 0 1 2 3 4 5 6 7 8 9 ;
HAIKU_DIGIT_MULT_2 = $(HAIKU_PAD_9) 0 2 4 6 8 0 2 4 6 8 ;
HAIKU_DIGIT_MULT_3 = $(HAIKU_PAD_9) 0 3 6 9 2 5 8 1 4 7 ;
HAIKU_DIGIT_MULT_4 = $(HAIKU_PAD_9) 0 4 8 2 6 0 4 8 2 6 ;
HAIKU_DIGIT_MULT_5 = $(HAIKU_PAD_9) 0 5 0 5 0 5 0 5 0 5 ;
HAIKU_DIGIT_MULT_6 = $(HAIKU_PAD_9) 0 6 2 8 4 0 6 2 8 4 ;
HAIKU_DIGIT_MULT_7 = $(HAIKU_PAD_9) 0 7 4 1 8 5 2 9 6 3 ;
HAIKU_DIGIT_MULT_8 = $(HAIKU_PAD_9) 0 8 6 4 2 0 8 6 4 2 ;
HAIKU_DIGIT_MULT_9 = $(HAIKU_PAD_9) 0 9 8 7 6 5 4 3 2 1 ;
HAIKU_DIGIT_MULT_CARRY_0 = $(HAIKU_PAD_9) 0 0 0 0 0 0 0 0 0 0 ;
HAIKU_DIGIT_MULT_CARRY_1 = $(HAIKU_PAD_9) 0 0 0 0 0 0 0 0 0 0 ;
HAIKU_DIGIT_MULT_CARRY_2 = $(HAIKU_PAD_9) 0 0 0 0 0 1 1 1 1 1 ;
HAIKU_DIGIT_MULT_CARRY_3 = $(HAIKU_PAD_9) 0 0 0 0 1 1 1 2 2 2 ;
HAIKU_DIGIT_MULT_CARRY_4 = $(HAIKU_PAD_9) 0 0 0 1 1 2 2 2 3 3 ;
HAIKU_DIGIT_MULT_CARRY_5 = $(HAIKU_PAD_9) 0 0 1 1 2 2 3 3 4 4 ;
HAIKU_DIGIT_MULT_CARRY_6 = $(HAIKU_PAD_9) 0 0 1 1 2 3 3 4 4 5 ;
HAIKU_DIGIT_MULT_CARRY_7 = $(HAIKU_PAD_9) 0 0 1 2 2 3 4 4 5 6 ;
HAIKU_DIGIT_MULT_CARRY_8 = $(HAIKU_PAD_9) 0 0 1 2 3 4 4 5 6 7 ;
HAIKU_DIGIT_MULT_CARRY_9 = $(HAIKU_PAD_9) 0 0 1 2 3 4 5 6 7 8 ;
# pragma mark - Number Operations
rule NormalizeNum number
{
# NormalizeNum <number> ;
local sign ;
if $(number[1]) = "-" || $(number[1] = "+" {
sign = $(number[1]) ;
number = $(number[2-]) ;
} else {
sign = "+" ;
}
# cut off leading zeros
local number = [ FReverse $(number) ] ;
while $(number[1]) = 0 {
number = $(number[2-]) ;
}
number = [ FReverse $(number) ] ;
# zero is respresented as + 0
if ! $(number) {
number = 0 ;
sign = "+" ;
}
return $(sign) $(number) ;
}
rule Num string : dontExit
{
# Num <number string> [ : <dontExit> ] ;
# split the string into three parts: sign, digits, and remainder
local temp = [ Match ([^0-9]*)([0-9]+)(.*) : $(string) ] ;
# there must be digits, but there must not be a remainder
if ! $(temp[2]) || $(temp[3]) {
if $(dontExit) {
return ;
}
Exit "Not a number" ;
}
# get the sign
local number ;
if ! $(temp[1]) {
number = "+" ;
} else if $(temp[1]) = "+" || $(temp[1]) = "-" {
number = $(temp[1]) ;
} else {
if $(dontExit) {
return ;
}
Exit "Not a number (sign)" ;
}
# split the digits
temp = $(temp[2]) ;
while $(temp[1]) {
# split off the last digit
temp = [ Match (.*)([0-9]) : $(temp[1]) ] ;
number += $(temp[2]) ;
}
# normalize
return [ NormalizeNum $(number) ] ;
}
rule Num2String number
{
# Num2String <number> ;
local sign = $(number[1]) ;
if $(sign) = "+" {
sign = "" ;
}
number = [ FReverse $(number[2-]) ] ;
return $(sign)$(number:J=) ;
}
rule NumGreaterAbs a : b
{
# NumGreaterAbs <a> : <b> ;
# we compare from least to most significant digit
local cmp = 0 ;
while $(a) && $(b) {
# chop off the first digit
local da = $(a[1]:E=0) ;
local db = $(b[1]:E=0) ;
a = $(a[2-]) ;
b = $(b[2-]) ;
if $(da) != $(db) {
if $(HAIKU_DIGIT_GREATER_$(da)[1$(db)]) {
cmp = 1 ;
} else {
cmp = -1 ;
}
}
}
# a is greater, if b is not longer and a is either longer or equally long
# and greater according to the digits comparison
if ! $(b) && ( $(a) || $(cmp) = 1 ) {
return 1 ;
}
return ;
}
rule AddNumAbs a : b
{
# AddNum <a> : <b> ;
@ -212,395 +60,3 @@ rule AddNumAbs a : b
return $(result) ;
}
rule SubNumAbs a : b
{
# SubNum <a> : <b> ;
local result ;
local carry ;
while $(a) && ( $(b) || $(carry) ) {
# chop off the first digit
local da = $(a[1]:E=0) ;
local db = $(b[1]:E=0) ;
a = $(a[2-]) ;
b = $(b[2-]) ;
# sub carry from the first digit
if $(carry) {
local daa = $(HAIKU_DIGIT_SUB_$(da)[11]) ;
carry = $(HAIKU_DIGIT_GREATER_$(daa)[1$(da)]) ;
da = $(daa) ;
}
# sub digits
local dr = $(HAIKU_DIGIT_SUB_$(da)[1$(db)]) ;
if $(HAIKU_DIGIT_GREATER_$(dr)[1$(da)]) {
carry = 1 ;
}
result += $(dr) ;
}
if $(b) || $(carry) {
Exit "Error: SubNumAbs: Can't subtract greater from smaller number." ;
}
return $(result) ;
}
rule NegNum a
{
# NegNum <a> ;
if $(a[1]) = "+" {
if $(a) = $(HAIKU_ZERO) {
return $(a) ;
}
return "-" $(a[2-]) ;
} else {
return "+" $(a[2-]) ;
}
}
rule AddNum a : b
{
# AddNum <a> : <b> ;
local signa = $(a[1]) ;
local signb = $(b[1]) ;
a = $(a[2-]) ;
b = $(b[2-]) ;
if $(signa) = $(signb) {
return $(signa) [ AddNumAbs $(a) : $(b) ] ;
} else {
local result ;
if [ NumGreaterAbs $(a) : $(b) ] {
result = $(signa) [ SubNumAbs $(a) : $(b) ] ;
} else {
result = $(signb) [ SubNumAbs $(b) : $(a) ] ;
}
return [ NormalizeNum $(result) ] ;
}
}
rule SubNum a : b
{
# SubNum <a> : <b> ;
return [ AddNum $(a) : [ NegNum $(b) ] ] ;
}
rule MultNumAbsDigit a : digit
{
# MultNumAbsDigit <a> : <digit> ;
local digitMultiples = $(HAIKU_DIGIT_MULT_$(digit)) ;
local digitCarries = $(HAIKU_DIGIT_MULT_CARRY_$(digit)) ;
local result ;
local carry = 0 ;
while $(a) || $(carry) != 0 {
# chop off the first digit
local da = $(a[1]:E=0) ;
a = $(a[2-]) ;
local dr = $(digitMultiples[1$(da)]) ;
# add carry to the resulting digit
if $(carry) {
local dra = $(HAIKU_DIGIT_ADD_$(dr)[1$(carry)]) ;
carry = $(HAIKU_DIGIT_GREATER_$(dr)[1$(dra)]:E=0) ;
dr = $(dra) ;
}
# new carry
carry = $(HAIKU_DIGIT_ADD_$(carry:E=0)[1$(digitCarries[1$(da)])]) ;
result += $(dr) ;
}
return $(result) ;
}
rule MultNum a : b
{
# MultNum <a> : <b> ;
# If one of the factors is 0, we save us computation and normalization.
if $(a) = $(HAIKU_ZERO) || $(b) = $(HAIKU_ZERO) {
return $(HAIKU_ZERO) ;
}
# get the sign for the result
local sign = "+" ;
if $(a[1]) != $(b[1]) {
sign = "-" ;
}
a = $(a[2-]) ;
b = $(b[2-]) ;
# multiply the individual digits of b with a and add up the result
local result = 0 ;
local prefix ;
while $(b) {
local db = $(b[1]) ;
b = $(b[2-]) ;
local adb = $(prefix) [ MultNumAbsDigit $(a) : $(db) ] ;
result = [ AddNumAbs $(result) : $(adb) ] ;
prefix += 0 ;
}
return $(sign) $(result) ;
}
rule NumGreater a : b
{
local signa = $(a[1]) ;
local signb = $(b[1]) ;
a = $(a[2-]) ;
b = $(b[2-]) ;
if $(signa) = $(signb) {
if $(signa) = "+" {
return [ NumGreaterAbs $(a) : $(b) ] ;
} else {
return [ NumGreaterAbs $(b) : $(a) ] ;
}
} else {
if $(signa) = "+" {
return 1 ;
} else {
return ;
}
}
}
# pragma mark - Number String Operations
rule Inc a
{
# Inc <number string a> ;
return [ Num2String [ AddNum [ Num $(a) ] : + 1 ] ] ;
}
rule Dec a
{
# Dec <number string a> ;
return [ Num2String [ AddNum [ Num $(a) ] : - 1 ] ] ;
}
rule Neg a
{
# Neg <number string a> ;
return [ Num2String [ NegNum [ Num $(a) ] ] ] ;
}
rule Add a : b
{
# Add <number string a> : <number string b> ;
return [ Num2String [ AddNum [ Num $(a) ] : [ Num $(b) ] ] ] ;
}
rule Sub a : b
{
# Sub <number string a> : <number string b> ;
return [ Num2String [ SubNum [ Num $(a) ] : [ Num $(b) ] ] ] ;
}
rule Mult a : b
{
# Mult <number string a> : <number string b> ;
return [ Num2String [ MultNum [ Num $(a) ] : [ Num $(b) ] ] ] ;
}
rule Equal a : b
{
# Equal <number string a> : <number string b> ;
if [ Num $(a) ] = [ Num $(b) ] {
return 1 ;
}
return ;
}
rule Less a : b
{
# Less <number string a> : <number string b> ;
return [ NumGreater [ Num $(b) ] : [ Num $(a) ] ] ;
}
rule Greater a : b
{
# Greater <number string a> : <number string b> ;
return [ NumGreater [ Num $(a) ] : [ Num $(b) ] ] ;
}
rule LessOrEqual a : b
{
# LessOrEqual <number string a> : <number string b> ;
if [ NumGreater [ Num $(a) ] : [ Num $(b) ] ] {
return ;
}
return 1 ;
}
rule GreaterOrEqual a : b
{
# GreaterOrEqual <number string a> : <number string b> ;
if [ NumGreater [ Num $(b) ] : [ Num $(a) ] ] {
return ;
}
return 1 ;
}
# pragma mark - Expression Parser
rule ParseAtom expression
{
# ParseAtom <expression> ;
# expression: '(' expression ')' | number
if $(expression[1]) = "(" {
local result = [ ParseExpression $(expression[2-]) ] ;
if $(result[2]) != ")" {
Exit "ParseAtom: Parse error: Expected \")\"." ;
}
return $(result[1]) $(result[3-]) ;
} else {
if ! $(expression) {
Exit "ParseAtom: Parse error: Unexpected end of expression." ;
}
local num = [ Num $(expression[1]) : 1 ] ;
if ! $(num) {
Exit "ParseAtom: Parse error: Expected number instead of:"
$(expression[1]) ;
}
return [ Num2String $(num) ] $(expression[2-]) ;
}
}
rule ParseUnary expression
{
# ParseUnary <expression> ;
# expression: ('+'/'-')* atom
if ! $(expression) {
Exit "ParseUnary: Parse error: Unexpected end of expression." ;
}
# eat all unary "+" and "-" operations
local neg ;
while $(expression[1]) = "+" || $(expression[1]) = "-" {
if $(expression[1]) = "-" {
if $(neg) {
neg = ;
} else {
neg = 1 ;
}
}
expression = $(expression[2-]) ;
}
local result = [ ParseAtom $(expression) ] ;
if $(neg) {
return [ Neg $(result[1]) ] $(result[2-]) ;
}
return $(result) ;
}
rule ParseTerm expression
{
# ParseTerm <expression> ;
# expression: unary ('*' unary)*
local result = [ ParseUnary $(expression) ] ;
local product = $(result[1]) ;
expression = $(result[2-]) ;
while $(expression[1]) = "*" {
# get the operation
local operation ;
operation = Mult ;
# parse the next operand
result = [ ParseUnary $(expression[2-]) ] ;
expression = $(result[2-]) ;
# compute the product
product = [ $(operation) $(product) : $(result[1]) ] ;
}
return $(product) $(expression) ;
}
rule ParseExpression expression
{
# ParseExpression <expression> ;
# expression: term ('+'/'-' term)*
local result = [ ParseTerm $(expression) ] ;
local sum = $(result[1]) ;
expression = $(result[2-]) ;
while $(expression[1]) = "+" || $(expression[1]) = "-" {
# get the operation
local operation ;
if $(expression[1]) = "+" {
operation = Add ;
} else {
operation = Sub ;
}
# parse the next operand
result = [ ParseTerm $(expression[2-]) ] ;
expression = $(result[2-]) ;
# compute the sum
sum = [ $(operation) $(sum) : $(result[1]) ] ;
}
return $(sum) $(expression) ;
}
rule Expr expression
{
# Expr <expression> ;
# tokenize the expression
local tokens ;
local string ;
for string in $(expression) {
while $(string) {
local split = [ Match "[ \t]*(-|[()+*]|[0-9]*)(.*)" : $(string) ] ;
if ! $(split[1]) {
Exit "Expr: Syntax error: Invalid token: \"$(string)\"." ;
}
tokens += $(split[1]) ;
string = $(split[2]) ;
}
}
local result = [ ParseExpression $(tokens) ] ;
if $(result[2-]) {
Exit "Expr: Garbage at end of expression:" $(result[2-]) ;
}
return $(result[1]) ;
}