Skip to content

Commit

Permalink
Make all other operators work in-class. cf. #583 (or #33 for that mat…
Browse files Browse the repository at this point in the history
…ter). Still no inheritance.. will see about that laterz.
  • Loading branch information
nddrylliog committed Feb 14, 2013
1 parent 6ec80f5 commit ba0432d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 16 deletions.
18 changes: 5 additions & 13 deletions source/rock/middle/ArrayAccess.ooc
Expand Up @@ -242,7 +242,7 @@ ArrayAccess: class extends Expression {
}

for (opDecl in tDecl operators) {
"Matching %s against %s" printfln(opDecl toString(), toString())
//"Matching %s against %s" printfln(opDecl toString(), toString())
score := getScore(opDecl, reqType, inAssign ? parent as BinaryOp : null, res)
if(score == -1) {
return Response LOOP
Expand Down Expand Up @@ -319,52 +319,44 @@ ArrayAccess: class extends Expression {

isResolved: func -> Bool { array isResolved() && type != null }
getScore: func (op: OperatorDecl, reqType: Type, assign: BinaryOp, res: Resolver) -> Int {
"op symbol = %s" printfln(op getSymbol())

if(!(op getSymbol() equals?(assign != null ? "[]=" : "[]"))) {
return 0 // not the right overload type - skip
}
diff := op getSymbol() endsWith?("=") ? 2 : 1
requiredArgs := indices getSize() + diff

fDecl := op getFunctionDecl()
"fDecl = %s" printfln(fDecl toString())

args := ArrayList<VariableDecl> new()
args addAll(fDecl getArguments())

if (fDecl owner) {
args add(0, fDecl owner getThisDecl())
}

"args size = %d, required = %d" printfln(args size, requiredArgs)

if(!args last() instanceOf?(VarArg) && (args getSize() != requiredArgs)) {
// not a match!
//if(res params veryVerbose) {
if(res params veryVerbose) {
"For %s vs %s, got %d args, %d indices, diff is %d - no luck!" format(op toString(), toString(), args getSize(), indices getSize(), diff) println()
//}
}
return 0
}

// Handle the array expression first, e.g. array[indices...]
opArray := args get(0)
if(opArray getType() == null || array getType() == null) {
"Null opArray" println()
return -1
}

arrayScore := array getType() getScore(opArray getType())
if(arrayScore == -1) {
"-1 arrayScore" println()
return -1
}

indexScore := 0
for(i in 0..(args getSize() - diff)) {
opIndex := args[i + 1]
index := indices[i]
"opIndex = %s, index = %s (diff = %d)" printfln(opIndex toString(), index toString(), diff)
//"opIndex = %s, index = %s (diff = %d)" printfln(opIndex toString(), index toString(), diff)
match {
case opIndex instanceOf?(VarArg) =>
indexScore += Type SCORE_SEED
Expand All @@ -388,7 +380,7 @@ ArrayAccess: class extends Expression {
reqScore := reqType ? fDecl getReturnType() getScore(reqType) : 0
if(reqScore == -1) return -1

"Score of %s for %s = %d (array %d, index %d, req %d)" printfln(op toString(), toString(), arrayScore + indexScore + reqScore, arrayScore, indexScore, reqScore)
//"Score of %s for %s = %d (array %d, index %d, req %d)" printfln(op toString(), toString(), arrayScore + indexScore + reqScore, arrayScore, indexScore, reqScore)

return arrayScore + indexScore + reqScore

Expand Down
45 changes: 42 additions & 3 deletions source/rock/middle/BinaryOp.ooc
Expand Up @@ -3,7 +3,7 @@ import ../frontend/Token
import Expression, Visitor, Type, Node, FunctionCall, OperatorDecl,
Import, Module, FunctionCall, ClassDecl, CoverDecl, AddressOf,
ArrayAccess, VariableAccess, Cast, NullLiteral, PropertyDecl,
Tuple, VariableDecl, FuncType
Tuple, VariableDecl, FuncType, TypeDecl
import tinker/[Trail, Resolver, Response, Errors]

OpType: enum {
Expand Down Expand Up @@ -423,6 +423,33 @@ BinaryOp: class extends Expression {

reqType := trail peek() getRequiredType()

// first we check the lhs's type
lhsType := left getType()

if (lhsType) {
lhsTypeRef := lhsType getRef()

match lhsTypeRef {
case tDecl: TypeDecl =>
if (tDecl isMeta) {
tDecl = tDecl getNonMeta()
}

for (opDecl in tDecl operators) {
"Matching %s against %s" printfln(opDecl toString(), toString())
score := getScore(opDecl, reqType)
if(score == -1) {
return Response LOOP
}
if(score > bestScore) {
bestScore = score
candidate = opDecl
}
}
}
}

// then we check the current module
for(opDecl in trail module() getOperators()) {
score := getScore(opDecl, reqType)
//if(score > 0) ("Considering " + opDecl toString() + " for " + toString() + ", score = %d\n") format(score) println()
Expand All @@ -433,6 +460,7 @@ BinaryOp: class extends Expression {
}
}

// and then the imports
for(imp in trail module() getAllImports()) {
module := imp getModule()
for(opDecl in module getOperators()) {
Expand All @@ -458,7 +486,13 @@ BinaryOp: class extends Expression {

fDecl := candidate getFunctionDecl()
fCall := FunctionCall new(fDecl getName(), token)
fCall getArguments() add(left)

if (fDecl owner) {
fCall expr = left
} else {
fCall getArguments() add(left)
}

fCall getArguments() add(right)
fCall setRef(fDecl)
if(!trail peek() replace(this, fCall)) {
Expand Down Expand Up @@ -490,8 +524,13 @@ BinaryOp: class extends Expression {
}

fDecl := op getFunctionDecl()
args := ArrayList<VariableDecl> new()
args addAll(fDecl getArguments())

if (fDecl owner) {
args add(0, fDecl owner getThisDecl())
}

args := fDecl getArguments()
if(args getSize() != 2) {
token module params errorHandler onError(InvalidBinaryOverload new(op token,
"Argl, you need 2 arguments to override the '%s' operator, not %d" format(symbol, args getSize())))
Expand Down

0 comments on commit ba0432d

Please sign in to comment.