Bitwise shift and modulo
This commit is contained in:
@@ -136,6 +136,13 @@ struct rxcc {
|
||||
case GREATER_THAN
|
||||
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 UNDEFINED
|
||||
@@ -164,8 +171,13 @@ struct rxcc {
|
||||
|
||||
case Addition
|
||||
case Subtraction
|
||||
|
||||
case Multiplication
|
||||
case Division
|
||||
case Modulo
|
||||
|
||||
case BitwiseShiftLeft
|
||||
case BitwiseShiftRight
|
||||
|
||||
case LessThan
|
||||
case LessThanOrEqualTo
|
||||
@@ -186,6 +198,7 @@ struct rxcc {
|
||||
// Expression variants
|
||||
case TermSequence
|
||||
case AdditiveExpressionSequence
|
||||
case BitwiseShiftExpressionSequence
|
||||
case RelationalExpressionSequence
|
||||
case EqualityExpressionSequence
|
||||
case LogicalAndExpressionSequence
|
||||
@@ -227,6 +240,7 @@ struct rxcc {
|
||||
|
||||
case MultiplicationPriorityOperator
|
||||
case AdditionPriorityOperator
|
||||
case BitwiseShiftPriorityOperator
|
||||
case InequalityPriorityOperator
|
||||
case EqualityPriorityOperator
|
||||
case LogicalAndPriorityOperator
|
||||
@@ -239,6 +253,7 @@ struct rxcc {
|
||||
case Expression
|
||||
case LogicalOrExpression
|
||||
case LogicalAndExpression
|
||||
case BitwiseShiftExpression
|
||||
case EqualityExpression
|
||||
case RelationalExpression
|
||||
case AdditiveExpression
|
||||
@@ -300,6 +315,18 @@ struct rxcc {
|
||||
.Division: [
|
||||
.Token(type: .DIVISION),
|
||||
],
|
||||
.Modulo: [
|
||||
.Token(type: .MODULO),
|
||||
],
|
||||
],
|
||||
|
||||
.BitwiseShiftPriorityOperator: [
|
||||
.BitwiseShiftLeft: [
|
||||
.Token(type: .BITWISE_SHIFT_LEFT),
|
||||
],
|
||||
.BitwiseShiftRight: [
|
||||
.Token(type: .BITWISE_SHIFT_RIGHT),
|
||||
],
|
||||
],
|
||||
|
||||
.InequalityPriorityOperator: [
|
||||
@@ -370,9 +397,16 @@ struct rxcc {
|
||||
],
|
||||
|
||||
.RelationalExpression: [
|
||||
.BitwiseShiftExpressionSequence: [
|
||||
.Construct(type: .BitwiseShiftExpression),
|
||||
.OperatorLoop(type: .InequalityPriorityOperator),
|
||||
]
|
||||
],
|
||||
|
||||
.BitwiseShiftExpression: [
|
||||
.AdditiveExpressionSequence: [
|
||||
.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: " == ")
|
||||
@@ -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: " >> ")
|
||||
|
||||
do {
|
||||
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")
|
||||
break
|
||||
}
|
||||
let variable: String = node.children[0].value
|
||||
|
||||
text += generateOutput(node.children[0])
|
||||
text += " push\t%eax\n"
|
||||
@@ -789,7 +827,7 @@ struct rxcc {
|
||||
}
|
||||
break
|
||||
|
||||
case .AdditiveExpressionSequence:
|
||||
case .BitwiseShiftExpressionSequence:
|
||||
var operation: ConstructVariant = .Error
|
||||
let count = node.children.count
|
||||
if count == 0 {
|
||||
@@ -845,6 +883,48 @@ struct rxcc {
|
||||
}
|
||||
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:
|
||||
var operation: ConstructVariant = .Error
|
||||
let count = node.children.count
|
||||
@@ -908,6 +988,7 @@ struct rxcc {
|
||||
case .Multiplication:
|
||||
text += " pop \t%ecx\n"
|
||||
text += " imul\t%ecx, %eax\n"
|
||||
break
|
||||
|
||||
case .Division:
|
||||
text += " movl\t%eax, %ecx\n" // Move e2 to ecx
|
||||
@@ -915,6 +996,16 @@ struct rxcc {
|
||||
text += " cdq\n" // Extend eax into edx
|
||||
text += " idivl\t%ecx\n" // Perform edx:eax / ecx
|
||||
// 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:
|
||||
if i != 0 {
|
||||
@@ -1212,7 +1303,7 @@ struct rxcc {
|
||||
}
|
||||
else if type != token.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
|
||||
}
|
||||
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_OR_EQUAL_TO }
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user