Added bit shift

This commit is contained in:
Sasha Koshka 2022-11-21 01:07:46 -05:00
parent 5836da01ef
commit 317ad4674d
3 changed files with 66 additions and 16 deletions

View File

@ -6,6 +6,7 @@ const (
ErrorUnknownOpcode Error = iota ErrorUnknownOpcode Error = iota
ErrorDivideByZero ErrorDivideByZero
ErrorWrongOperandCount ErrorWrongOperandCount
ErrorNegativeShiftAmount
) )
func (err Error) Error () (description string) { func (err Error) Error () (description string) {
@ -15,7 +16,9 @@ func (err Error) Error () (description string) {
case ErrorDivideByZero: case ErrorDivideByZero:
description = "division by zero" description = "division by zero"
case ErrorWrongOperandCount: case ErrorWrongOperandCount:
description = "wrong amount of operands" description = "wrong operand amount"
case ErrorNegativeShiftAmount:
description = "negative shift amount"
} }
return return
} }

11
main.go
View File

@ -80,7 +80,10 @@ func onPress (button stone.Button) {
redraw() redraw()
application.Draw() application.Draw()
case '+', '-', '*', '/', 'p', 'r', '%', '|', '~', '&', '^', 'm': case
'+', '-', '*', '/', 'p', 'r', '%', '|', '~', '&', '^', 'm',
'<', '>':
insertOperation(rune(button)) insertOperation(rune(button))
redraw() redraw()
application.Draw() application.Draw()
@ -232,6 +235,8 @@ func insertOperation (symbol rune) {
case '~': opcode = OpcodeNot case '~': opcode = OpcodeNot
case '&': opcode = OpcodeAnd case '&': opcode = OpcodeAnd
case '^': opcode = OpcodeXor case '^': opcode = OpcodeXor
case '<': opcode = OpcodeLeftShift
case '>': opcode = OpcodeRightShift
case 'm': opcode = OpcodeMean case 'm': opcode = OpcodeMean
} }
@ -341,6 +346,9 @@ func drawInput () {
func drawNumberReadouts () { func drawNumberReadouts () {
_, height := application.Size() _, height := application.Size()
clear(0, height - 10, 25, 10)
var number int64 var number int64
var err error var err error
if selectedExpression != nil { if selectedExpression != nil {
@ -348,7 +356,6 @@ func drawNumberReadouts () {
} }
if err != nil { if err != nil {
clear(0, height - 10, 25, 10)
application.SetDot((25 - len(err.Error())) / 2, height - 6) application.SetDot((25 - len(err.Error())) / 2, height - 6)
fmt.Fprint(application, err.Error()) fmt.Fprint(application, err.Error())
} else { } else {

66
tree.go
View File

@ -24,25 +24,29 @@ const (
OpcodeNot OpcodeNot
OpcodeAnd OpcodeAnd
OpcodeXor OpcodeXor
OpcodeLeftShift
OpcodeRightShift
OpcodeMean OpcodeMean
) )
func (opcode Opcode) String () (output string) { func (opcode Opcode) String () (output string) {
switch opcode { switch opcode {
case OpcodeUnknown: output = "?" case OpcodeUnknown: output = "?"
case OpcodeAdd: output = "+" case OpcodeAdd: output = "+"
case OpcodeSubtract: output = "-" case OpcodeSubtract: output = "-"
case OpcodeMultiply: output = "*" case OpcodeMultiply: output = "*"
case OpcodeDivide: output = "/" case OpcodeDivide: output = "/"
case OpcodePower: output = "p" case OpcodePower: output = "p"
case OpcodeRoot: output = "r" case OpcodeRoot: output = "r"
case OpcodeModulo: output = "%" case OpcodeModulo: output = "%"
case OpcodeOr: output = "|" case OpcodeOr: output = "|"
case OpcodeNot: output = "~" case OpcodeNot: output = "~"
case OpcodeAnd: output = "&" case OpcodeAnd: output = "&"
case OpcodeXor: output = "^" case OpcodeXor: output = "^"
case OpcodeMean: output = "mean" case OpcodeLeftShift: output = "<<"
case OpcodeRightShift: output = ">>"
case OpcodeMean: output = "mean"
} }
return return
} }
@ -341,6 +345,42 @@ func (operation *Operation) Solution () (solution int64, err error) {
solution ^= subSolution solution ^= subSolution
} }
} }
case OpcodeLeftShift:
if len(operation.operands) != 2 {
err = ErrorWrongOperandCount
return
}
var left, right int64
left, err = operation.operands[0].Solution()
if err != nil { return }
right, err = operation.operands[1].Solution()
if err != nil { return }
if right < 0 {
err = ErrorNegativeShiftAmount
return
}
solution = left << right
case OpcodeRightShift:
if len(operation.operands) != 2 {
err = ErrorWrongOperandCount
return
}
var left, right int64
left, err = operation.operands[0].Solution()
if err != nil { return }
right, err = operation.operands[1].Solution()
if err != nil { return }
if right < 0 {
err = ErrorNegativeShiftAmount
return
}
solution = left >> right
case OpcodeMean: case OpcodeMean:
if len(operation.operands) == 0 { break } if len(operation.operands) == 0 { break }
for _, operand := range operation.operands { for _, operand := range operation.operands {