Bitwise shift and modulo
This commit is contained in:
@@ -136,6 +136,13 @@ struct rxcc {
|
|||||||
case GREATER_THAN
|
case GREATER_THAN
|
||||||
case GREATER_THAN_OR_EQUAL_TO
|
case GREATER_THAN_OR_EQUAL_TO
|
||||||
|
|
||||||
|
case MODULO
|
||||||
|
case BITWISE_AND
|
||||||
|
case BITWISE_OR
|
||||||
|
case BITWISE_XOR
|
||||||
|
case BITWISE_SHIFT_LEFT
|
||||||
|
case BITWISE_SHIFT_RIGHT
|
||||||
|
|
||||||
case ASSIGNMENT
|
case ASSIGNMENT
|
||||||
|
|
||||||
case UNDEFINED
|
case UNDEFINED
|
||||||
@@ -164,8 +171,13 @@ struct rxcc {
|
|||||||
|
|
||||||
case Addition
|
case Addition
|
||||||
case Subtraction
|
case Subtraction
|
||||||
|
|
||||||
case Multiplication
|
case Multiplication
|
||||||
case Division
|
case Division
|
||||||
|
case Modulo
|
||||||
|
|
||||||
|
case BitwiseShiftLeft
|
||||||
|
case BitwiseShiftRight
|
||||||
|
|
||||||
case LessThan
|
case LessThan
|
||||||
case LessThanOrEqualTo
|
case LessThanOrEqualTo
|
||||||
@@ -186,6 +198,7 @@ struct rxcc {
|
|||||||
// Expression variants
|
// Expression variants
|
||||||
case TermSequence
|
case TermSequence
|
||||||
case AdditiveExpressionSequence
|
case AdditiveExpressionSequence
|
||||||
|
case BitwiseShiftExpressionSequence
|
||||||
case RelationalExpressionSequence
|
case RelationalExpressionSequence
|
||||||
case EqualityExpressionSequence
|
case EqualityExpressionSequence
|
||||||
case LogicalAndExpressionSequence
|
case LogicalAndExpressionSequence
|
||||||
@@ -227,6 +240,7 @@ struct rxcc {
|
|||||||
|
|
||||||
case MultiplicationPriorityOperator
|
case MultiplicationPriorityOperator
|
||||||
case AdditionPriorityOperator
|
case AdditionPriorityOperator
|
||||||
|
case BitwiseShiftPriorityOperator
|
||||||
case InequalityPriorityOperator
|
case InequalityPriorityOperator
|
||||||
case EqualityPriorityOperator
|
case EqualityPriorityOperator
|
||||||
case LogicalAndPriorityOperator
|
case LogicalAndPriorityOperator
|
||||||
@@ -239,6 +253,7 @@ struct rxcc {
|
|||||||
case Expression
|
case Expression
|
||||||
case LogicalOrExpression
|
case LogicalOrExpression
|
||||||
case LogicalAndExpression
|
case LogicalAndExpression
|
||||||
|
case BitwiseShiftExpression
|
||||||
case EqualityExpression
|
case EqualityExpression
|
||||||
case RelationalExpression
|
case RelationalExpression
|
||||||
case AdditiveExpression
|
case AdditiveExpression
|
||||||
@@ -300,6 +315,18 @@ struct rxcc {
|
|||||||
.Division: [
|
.Division: [
|
||||||
.Token(type: .DIVISION),
|
.Token(type: .DIVISION),
|
||||||
],
|
],
|
||||||
|
.Modulo: [
|
||||||
|
.Token(type: .MODULO),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
.BitwiseShiftPriorityOperator: [
|
||||||
|
.BitwiseShiftLeft: [
|
||||||
|
.Token(type: .BITWISE_SHIFT_LEFT),
|
||||||
|
],
|
||||||
|
.BitwiseShiftRight: [
|
||||||
|
.Token(type: .BITWISE_SHIFT_RIGHT),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
.InequalityPriorityOperator: [
|
.InequalityPriorityOperator: [
|
||||||
@@ -370,9 +397,16 @@ struct rxcc {
|
|||||||
],
|
],
|
||||||
|
|
||||||
.RelationalExpression: [
|
.RelationalExpression: [
|
||||||
|
.BitwiseShiftExpressionSequence: [
|
||||||
|
.Construct(type: .BitwiseShiftExpression),
|
||||||
|
.OperatorLoop(type: .InequalityPriorityOperator),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
.BitwiseShiftExpression: [
|
||||||
.AdditiveExpressionSequence: [
|
.AdditiveExpressionSequence: [
|
||||||
.Construct(type: .AdditiveExpression),
|
.Construct(type: .AdditiveExpression),
|
||||||
.OperatorLoop(type: .InequalityPriorityOperator),
|
.OperatorLoop(type: .BitwiseShiftPriorityOperator),
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -520,6 +554,9 @@ struct rxcc {
|
|||||||
line = line.replacing("<", with: " < ")
|
line = line.replacing("<", with: " < ")
|
||||||
line = line.replacing(">", with: " > ")
|
line = line.replacing(">", with: " > ")
|
||||||
line = line.replacing("=", with: " = ")
|
line = line.replacing("=", with: " = ")
|
||||||
|
line = line.replacing("&", with: " & ")
|
||||||
|
line = line.replacing("|", with: " | ")
|
||||||
|
line = line.replacing("^", with: " ^ ")
|
||||||
line = line.replacing("&&", with: " && ")
|
line = line.replacing("&&", with: " && ")
|
||||||
line = line.replacing("||", with: " || ")
|
line = line.replacing("||", with: " || ")
|
||||||
line = line.replacing("==", with: " == ")
|
line = line.replacing("==", with: " == ")
|
||||||
@@ -527,6 +564,8 @@ struct rxcc {
|
|||||||
line = line.replacing(/! *=/, with: " != ")
|
line = line.replacing(/! *=/, with: " != ")
|
||||||
line = line.replacing(/< *=/, with: " <= ")
|
line = line.replacing(/< *=/, with: " <= ")
|
||||||
line = line.replacing(/> *=/, with: " >= ")
|
line = line.replacing(/> *=/, with: " >= ")
|
||||||
|
line = line.replacing(/< *</, with: " << ")
|
||||||
|
line = line.replacing(/> *>/, with: " >> ")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let tokens: [Substring] = line.split(separator: try Regex(" +"))
|
let tokens: [Substring] = line.split(separator: try Regex(" +"))
|
||||||
@@ -610,7 +649,6 @@ struct rxcc {
|
|||||||
print("ERROR: \(node.variant) with more or less than 1 child")
|
print("ERROR: \(node.variant) with more or less than 1 child")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
let variable: String = node.children[0].value
|
|
||||||
|
|
||||||
text += generateOutput(node.children[0])
|
text += generateOutput(node.children[0])
|
||||||
text += " push\t%eax\n"
|
text += " push\t%eax\n"
|
||||||
@@ -789,7 +827,7 @@ struct rxcc {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case .AdditiveExpressionSequence:
|
case .BitwiseShiftExpressionSequence:
|
||||||
var operation: ConstructVariant = .Error
|
var operation: ConstructVariant = .Error
|
||||||
let count = node.children.count
|
let count = node.children.count
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
@@ -845,6 +883,48 @@ struct rxcc {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case .AdditiveExpressionSequence:
|
||||||
|
var operation: ConstructVariant = .Error
|
||||||
|
let count = node.children.count
|
||||||
|
if count == 0 {
|
||||||
|
print("ERROR: \(node.variant) with no children")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for i in 0...count - 1 {
|
||||||
|
let child: SyntaxTreeNode = node.children[i]
|
||||||
|
|
||||||
|
// Operation
|
||||||
|
if i % 2 == 1 {
|
||||||
|
operation = child.variant
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
text += generateOutput(child)
|
||||||
|
|
||||||
|
switch operation {
|
||||||
|
case .BitwiseShiftLeft:
|
||||||
|
text += " movl\t%eax, %ecx\n" // Move e2 to ecx
|
||||||
|
text += " pop \t%eax\n" // Move e1 to eax
|
||||||
|
text += " sal \t%cl, %eax\n" // Perform e1 << e2; result in e1
|
||||||
|
|
||||||
|
case .BitwiseShiftRight:
|
||||||
|
text += " movl\t%eax, %ecx\n" // Move e2 to ecx
|
||||||
|
text += " pop \t%eax\n" // Move e1 to eax
|
||||||
|
text += " sar \t%cl, %eax\n" // Perform e1 >> e2; result in e1
|
||||||
|
|
||||||
|
default:
|
||||||
|
if i != 0 {
|
||||||
|
print("Unknown operation \"\(operation)\" in \(node.variant)")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != node.children.count - 1 {
|
||||||
|
text += " push\t%eax\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
case .TermSequence:
|
case .TermSequence:
|
||||||
var operation: ConstructVariant = .Error
|
var operation: ConstructVariant = .Error
|
||||||
let count = node.children.count
|
let count = node.children.count
|
||||||
@@ -908,6 +988,7 @@ struct rxcc {
|
|||||||
case .Multiplication:
|
case .Multiplication:
|
||||||
text += " pop \t%ecx\n"
|
text += " pop \t%ecx\n"
|
||||||
text += " imul\t%ecx, %eax\n"
|
text += " imul\t%ecx, %eax\n"
|
||||||
|
break
|
||||||
|
|
||||||
case .Division:
|
case .Division:
|
||||||
text += " movl\t%eax, %ecx\n" // Move e2 to ecx
|
text += " movl\t%eax, %ecx\n" // Move e2 to ecx
|
||||||
@@ -915,6 +996,16 @@ struct rxcc {
|
|||||||
text += " cdq\n" // Extend eax into edx
|
text += " cdq\n" // Extend eax into edx
|
||||||
text += " idivl\t%ecx\n" // Perform edx:eax / ecx
|
text += " idivl\t%ecx\n" // Perform edx:eax / ecx
|
||||||
// eax = quotient; edx rem.
|
// eax = quotient; edx rem.
|
||||||
|
break
|
||||||
|
|
||||||
|
case .Modulo:
|
||||||
|
text += " movl\t%eax, %ecx\n" // Move e2 to ecx
|
||||||
|
text += " pop \t%eax\n" // Fetch e1 off stack into eax
|
||||||
|
text += " cdq\n" // Extend eax into edx
|
||||||
|
text += " idivl\t%ecx\n" // Perform edx:eax / ecx
|
||||||
|
// eax = quotient; edx rem.
|
||||||
|
text += " movl\t%edx, %eax\n" // Move remainder to eax
|
||||||
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
@@ -1212,7 +1303,7 @@ struct rxcc {
|
|||||||
}
|
}
|
||||||
else if type != token.type {
|
else if type != token.type {
|
||||||
print("\(indent)Failed to validate token \"\(token.content)\". Expected \"\(type)\"")
|
print("\(indent)Failed to validate token \"\(token.content)\". Expected \"\(type)\"")
|
||||||
//print("\(indent)AKA, \(type) not equal to \(token.type)")
|
print("\(indent)AKA, \(type) not equal to \(token.type)")
|
||||||
return .Invalid
|
return .Invalid
|
||||||
}
|
}
|
||||||
print("\(indent)Validated token \"\(token.content)\"")
|
print("\(indent)Validated token \"\(token.content)\"")
|
||||||
@@ -1262,6 +1353,12 @@ struct rxcc {
|
|||||||
else if token.firstMatch(of: /^>$/) != nil { return .GREATER_THAN }
|
else if token.firstMatch(of: /^>$/) != nil { return .GREATER_THAN }
|
||||||
else if token.firstMatch(of: /^>=$/) != nil { return .GREATER_THAN_OR_EQUAL_TO }
|
else if token.firstMatch(of: /^>=$/) != nil { return .GREATER_THAN_OR_EQUAL_TO }
|
||||||
else if token.firstMatch(of: /^=$/) != nil { return .ASSIGNMENT }
|
else if token.firstMatch(of: /^=$/) != nil { return .ASSIGNMENT }
|
||||||
|
else if token.firstMatch(of: /^%$/) != nil { return .MODULO }
|
||||||
|
else if token.firstMatch(of: /^&$/) != nil { return .BITWISE_AND }
|
||||||
|
else if token.firstMatch(of: /^\|$/) != nil { return .BITWISE_OR }
|
||||||
|
else if token.firstMatch(of: /^\^$/) != nil { return .BITWISE_XOR }
|
||||||
|
else if token.firstMatch(of: /^<<$/) != nil { return .BITWISE_SHIFT_LEFT }
|
||||||
|
else if token.firstMatch(of: /^>>$/) != nil { return .BITWISE_SHIFT_RIGHT }
|
||||||
|
|
||||||
return .UNDEFINED
|
return .UNDEFINED
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user