val Constant, Variable, Operator
= Value
type ExpressionType
= Value
}
case class Expression
(expressionType
: ExpressionType.
ExpressionType, index
: Int
)
def Variable
= new Variable
{}
val Plus, Minus, Multiply, Divide
= Value
type OperatorType
= Value
}
case class Operator
(operatorType
: OperatorType.
OperatorType, a
: Expression, b
: Expression
)
case class ConstantStore
(constants
: Array
[Float
],
var count
: Int
) def constantStore
(size
: Int
) = ConstantStore
(Array.
ofDim(size
),
0)
case class VariableStore
(variables
: Array
[Variable
],
var count
: Int
) def variableStore
(size
: Int
) = VariableStore
(Array.
ofDim(size
),
0)
case class OperatorStore
(operators
: Array
[Operator
],
var count
: Int
) def operatorStore
(size
: Int
) = OperatorStore
(Array.
ofDim(size
),
0)
constantStore: ConstantStore,
variableStore: VariableStore,
operatorStore: OperatorStore
)
def constant
(environment
: Environment, value
: Float
) = { val store
= environment.
constantStore if(count
< store.
constants.
length) { store.constants(count) = value
store.count += 1
Expression(ExpressionType.Constant, count)
}
Expression(ExpressionType.Constant, -1)
}
}
def variable
(environment
: Environment, variable
: Variable
) = { val store
= environment.
variableStore if(count
< store.
variables.
length) { store.variables(count) = variable
store.count += 1
Expression(ExpressionType.Variable, count)
}
Expression(ExpressionType.Variable, -1)
}
}
def operator
(environment
: Environment, operator
: Operator
) = { val store
= environment.
operatorStore if(count
< store.
operators.
length) { store.operators(count) = operator
store.count += 1
Expression(ExpressionType.Operator, count)
}
Expression(ExpressionType.Operator, -1)
}
}
def plus
(environment
: Environment, a
: Expression, b
: Expression
) = operator(environment, Operator(OperatorType.Plus, a, b))
def minus
(environment
: Environment, a
: Expression, b
: Expression
) = operator(environment, Operator(OperatorType.Minus, a, b))
def multiply
(environment
: Environment, a
: Expression, b
: Expression
) = operator(environment, Operator(OperatorType.Multiply, a, b))
def divide
(environment
: Environment, a
: Expression, b
: Expression
) = operator(environment, Operator(OperatorType.Divide, a, b))
def result
(environment
: Environment, expression
: Expression, context
: Map
[Variable, Float
]): Float
= { expression.
expressionType match { case ExpressionType.
Constant => environment.constantStore.constants(expression.index)
case ExpressionType.
Variable => context(environment.variableStore.variables(expression.index))
case ExpressionType.
Operator => val operator
= environment.
operatorStore.
operators(expression.
index) operator.
operatorType match { case OperatorType.
Plus => result(environment, operator.a, context) +
result(environment, operator.b, context)
case OperatorType.
Minus => result(environment, operator.a, context) -
result(environment, operator.b, context)
case OperatorType.
Multiply => result(environment, operator.a, context) *
result(environment, operator.b, context)
case OperatorType.
Divide => result(environment, operator.a, context) /
result(environment, operator.b, context)
}
}
}
}
val env
= Environment
(constantStore
(10), variableStore
(10), operatorStore
(10))
val expression
= plus
(env,
minus(env,
multiply(env,
divide(env,
variable(env, a),
variable(env, b)
),
variable(env, c)
),
variable(env, d)
),
constant(env, 5f)
)
val context
= Map
(a -
> 1f, b -
> 2f, c -
> 3f, d -
> 4f
) println(result(env, expression, context))
}
b2JqZWN0IFN5bWJvbGljRXhwcmVzc2lvbnMgewoJCglvYmplY3QgRXhwcmVzc2lvblR5cGUgZXh0ZW5kcyBFbnVtZXJhdGlvbiB7CgkJdmFsIENvbnN0YW50LCBWYXJpYWJsZSwgT3BlcmF0b3IgPSBWYWx1ZQoJCXR5cGUgRXhwcmVzc2lvblR5cGUgPSBWYWx1ZQoJfQoKCWNhc2UgY2xhc3MgRXhwcmVzc2lvbihleHByZXNzaW9uVHlwZTogRXhwcmVzc2lvblR5cGUuRXhwcmVzc2lvblR5cGUsIGluZGV4OiBJbnQpCgkKCXRyYWl0IFZhcmlhYmxlCglkZWYgVmFyaWFibGUgPSBuZXcgVmFyaWFibGUge30KCQoJb2JqZWN0IE9wZXJhdG9yVHlwZSBleHRlbmRzIEVudW1lcmF0aW9uIHsKCQl2YWwgUGx1cywgTWludXMsIE11bHRpcGx5LCBEaXZpZGUgPSBWYWx1ZQoJCXR5cGUgT3BlcmF0b3JUeXBlID0gVmFsdWUKCX0KCQoJY2FzZSBjbGFzcyBPcGVyYXRvcihvcGVyYXRvclR5cGU6IE9wZXJhdG9yVHlwZS5PcGVyYXRvclR5cGUsIGE6IEV4cHJlc3Npb24sIGI6IEV4cHJlc3Npb24pCgkKCWNhc2UgY2xhc3MgQ29uc3RhbnRTdG9yZShjb25zdGFudHM6IEFycmF5W0Zsb2F0XSwgdmFyIGNvdW50OiBJbnQpCglkZWYgY29uc3RhbnRTdG9yZShzaXplOiBJbnQpID0gQ29uc3RhbnRTdG9yZShBcnJheS5vZkRpbShzaXplKSwgMCkKCQoJY2FzZSBjbGFzcyBWYXJpYWJsZVN0b3JlKHZhcmlhYmxlczogQXJyYXlbVmFyaWFibGVdLCB2YXIgY291bnQ6IEludCkKCWRlZiB2YXJpYWJsZVN0b3JlKHNpemU6IEludCkgPSBWYXJpYWJsZVN0b3JlKEFycmF5Lm9mRGltKHNpemUpLCAwKQoKCWNhc2UgY2xhc3MgT3BlcmF0b3JTdG9yZShvcGVyYXRvcnM6IEFycmF5W09wZXJhdG9yXSwgdmFyIGNvdW50OiBJbnQpCglkZWYgb3BlcmF0b3JTdG9yZShzaXplOiBJbnQpID0gT3BlcmF0b3JTdG9yZShBcnJheS5vZkRpbShzaXplKSwgMCkKCQoJY2FzZSBjbGFzcyBFbnZpcm9ubWVudCgKCQljb25zdGFudFN0b3JlOiBDb25zdGFudFN0b3JlLAoJCXZhcmlhYmxlU3RvcmU6IFZhcmlhYmxlU3RvcmUsCgkJb3BlcmF0b3JTdG9yZTogT3BlcmF0b3JTdG9yZQoJKQoJCglkZWYgY29uc3RhbnQoZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LCB2YWx1ZTogRmxvYXQpID0gewoJCXZhbCBzdG9yZSA9IGVudmlyb25tZW50LmNvbnN0YW50U3RvcmUKCQl2YWwgY291bnQgPSBzdG9yZS5jb3VudAoJCWlmKGNvdW50IDwgc3RvcmUuY29uc3RhbnRzLmxlbmd0aCkgewoJCQlzdG9yZS5jb25zdGFudHMoY291bnQpID0gdmFsdWUKCQkJc3RvcmUuY291bnQgKz0gMQoJCQlFeHByZXNzaW9uKEV4cHJlc3Npb25UeXBlLkNvbnN0YW50LCBjb3VudCkKCQl9CgkJZWxzZSB7CgkJCUV4cHJlc3Npb24oRXhwcmVzc2lvblR5cGUuQ29uc3RhbnQsIC0xKQoJCX0KCX0KCglkZWYgdmFyaWFibGUoZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LCB2YXJpYWJsZTogVmFyaWFibGUpID0gewoJCXZhbCBzdG9yZSA9IGVudmlyb25tZW50LnZhcmlhYmxlU3RvcmUKCQl2YWwgY291bnQgPSBzdG9yZS5jb3VudAoJCWlmKGNvdW50IDwgc3RvcmUudmFyaWFibGVzLmxlbmd0aCkgewoJCQlzdG9yZS52YXJpYWJsZXMoY291bnQpID0gdmFyaWFibGUKCQkJc3RvcmUuY291bnQgKz0gMQoJCQlFeHByZXNzaW9uKEV4cHJlc3Npb25UeXBlLlZhcmlhYmxlLCBjb3VudCkKCQl9CgkJZWxzZSB7CgkJCUV4cHJlc3Npb24oRXhwcmVzc2lvblR5cGUuVmFyaWFibGUsIC0xKQoJCX0KCX0KCQoJZGVmIG9wZXJhdG9yKGVudmlyb25tZW50OiBFbnZpcm9ubWVudCwgb3BlcmF0b3I6IE9wZXJhdG9yKSA9IHsKCQl2YWwgc3RvcmUgPSBlbnZpcm9ubWVudC5vcGVyYXRvclN0b3JlCgkJdmFsIGNvdW50ID0gc3RvcmUuY291bnQKCQlpZihjb3VudCA8IHN0b3JlLm9wZXJhdG9ycy5sZW5ndGgpIHsKCQkJc3RvcmUub3BlcmF0b3JzKGNvdW50KSA9IG9wZXJhdG9yCgkJCXN0b3JlLmNvdW50ICs9IDEKCQkJRXhwcmVzc2lvbihFeHByZXNzaW9uVHlwZS5PcGVyYXRvciwgY291bnQpCgkJfQoJCWVsc2UgewoJCQlFeHByZXNzaW9uKEV4cHJlc3Npb25UeXBlLk9wZXJhdG9yLCAtMSkKCQl9Cgl9CgoJZGVmIHBsdXMoZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LCBhOiBFeHByZXNzaW9uLCBiOiBFeHByZXNzaW9uKSA9CgkJb3BlcmF0b3IoZW52aXJvbm1lbnQsIE9wZXJhdG9yKE9wZXJhdG9yVHlwZS5QbHVzLCBhLCBiKSkKCglkZWYgbWludXMoZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LCBhOiBFeHByZXNzaW9uLCBiOiBFeHByZXNzaW9uKSA9CgkJb3BlcmF0b3IoZW52aXJvbm1lbnQsIE9wZXJhdG9yKE9wZXJhdG9yVHlwZS5NaW51cywgYSwgYikpCgoJZGVmIG11bHRpcGx5KGVudmlyb25tZW50OiBFbnZpcm9ubWVudCwgYTogRXhwcmVzc2lvbiwgYjogRXhwcmVzc2lvbikgPQoJCW9wZXJhdG9yKGVudmlyb25tZW50LCBPcGVyYXRvcihPcGVyYXRvclR5cGUuTXVsdGlwbHksIGEsIGIpKQoKCWRlZiBkaXZpZGUoZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LCBhOiBFeHByZXNzaW9uLCBiOiBFeHByZXNzaW9uKSA9CgkJb3BlcmF0b3IoZW52aXJvbm1lbnQsIE9wZXJhdG9yKE9wZXJhdG9yVHlwZS5EaXZpZGUsIGEsIGIpKQoKCWRlZiByZXN1bHQoZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LCBleHByZXNzaW9uOiBFeHByZXNzaW9uLCBjb250ZXh0OiBNYXBbVmFyaWFibGUsIEZsb2F0XSk6IEZsb2F0ID0gewoJCWV4cHJlc3Npb24uZXhwcmVzc2lvblR5cGUgbWF0Y2ggewoJCQljYXNlIEV4cHJlc3Npb25UeXBlLkNvbnN0YW50ID0+CgkJCQllbnZpcm9ubWVudC5jb25zdGFudFN0b3JlLmNvbnN0YW50cyhleHByZXNzaW9uLmluZGV4KQoKCQkJY2FzZSBFeHByZXNzaW9uVHlwZS5WYXJpYWJsZSA9PgoJCQkJY29udGV4dChlbnZpcm9ubWVudC52YXJpYWJsZVN0b3JlLnZhcmlhYmxlcyhleHByZXNzaW9uLmluZGV4KSkKCgkJCWNhc2UgRXhwcmVzc2lvblR5cGUuT3BlcmF0b3IgPT4KCQkJCXZhbCBvcGVyYXRvciA9IGVudmlyb25tZW50Lm9wZXJhdG9yU3RvcmUub3BlcmF0b3JzKGV4cHJlc3Npb24uaW5kZXgpCgkJCQlvcGVyYXRvci5vcGVyYXRvclR5cGUgbWF0Y2ggewoJCQkJCWNhc2UgT3BlcmF0b3JUeXBlLlBsdXMgPT4KCQkJCQkJcmVzdWx0KGVudmlyb25tZW50LCBvcGVyYXRvci5hLCBjb250ZXh0KSArCgkJCQkJCQlyZXN1bHQoZW52aXJvbm1lbnQsIG9wZXJhdG9yLmIsIGNvbnRleHQpCgoJCQkJCWNhc2UgT3BlcmF0b3JUeXBlLk1pbnVzID0+CgkJCQkJCXJlc3VsdChlbnZpcm9ubWVudCwgb3BlcmF0b3IuYSwgY29udGV4dCkgLQoJCQkJCQkJcmVzdWx0KGVudmlyb25tZW50LCBvcGVyYXRvci5iLCBjb250ZXh0KQoKCQkJCQljYXNlIE9wZXJhdG9yVHlwZS5NdWx0aXBseSA9PgoJCQkJCQlyZXN1bHQoZW52aXJvbm1lbnQsIG9wZXJhdG9yLmEsIGNvbnRleHQpICoKCQkJCQkJCXJlc3VsdChlbnZpcm9ubWVudCwgb3BlcmF0b3IuYiwgY29udGV4dCkKCgkJCQkJY2FzZSBPcGVyYXRvclR5cGUuRGl2aWRlID0+CgkJCQkJCXJlc3VsdChlbnZpcm9ubWVudCwgb3BlcmF0b3IuYSwgY29udGV4dCkgLwoJCQkJCQkJcmVzdWx0KGVudmlyb25tZW50LCBvcGVyYXRvci5iLCBjb250ZXh0KQoJCQkJfQoJCX0KCX0KCn0KCm9iamVjdCBNYWluIGV4dGVuZHMgQXBwIHsKCWltcG9ydCBTeW1ib2xpY0V4cHJlc3Npb25zLl8KCQoJdmFsIGVudiA9IEVudmlyb25tZW50KGNvbnN0YW50U3RvcmUoMTApLCB2YXJpYWJsZVN0b3JlKDEwKSwgb3BlcmF0b3JTdG9yZSgxMCkpCgkKCXZhbCBhID0gVmFyaWFibGUKCXZhbCBiID0gVmFyaWFibGUKCXZhbCBjID0gVmFyaWFibGUKCXZhbCBkID0gVmFyaWFibGUKCQoJdmFsIGV4cHJlc3Npb24gPSBwbHVzKGVudiwKCQltaW51cyhlbnYsCgkJCW11bHRpcGx5KGVudiwKCQkJCWRpdmlkZShlbnYsCgkJCQkJdmFyaWFibGUoZW52LCBhKSwKCQkJCQl2YXJpYWJsZShlbnYsIGIpCgkJCQkpLAoJCQkJdmFyaWFibGUoZW52LCBjKQoJCQkpLAoJCQl2YXJpYWJsZShlbnYsIGQpCgkJKSwKCQljb25zdGFudChlbnYsIDVmKQoJKQoJCgl2YWwgY29udGV4dCA9IE1hcChhIC0+IDFmLCBiIC0+IDJmLCBjIC0+IDNmLCBkIC0+IDRmKQoJcHJpbnRsbihyZXN1bHQoZW52LCBleHByZXNzaW9uLCBjb250ZXh0KSkKfQ==