Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Master ports: nested arrays fix, accessing covered methods and fields…
… without a cast
  • Loading branch information
alexnask committed Nov 12, 2012
1 parent d8e806b commit 13135e0
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 15 deletions.
18 changes: 13 additions & 5 deletions source/rock/backend/cnaughty/CGenerator.ooc
Expand Up @@ -292,7 +292,15 @@ CGenerator: class extends Skeleton {
type := arrLit getType()
if(!type instanceOf?(PointerType)) Exception new(This, "Array literal type %s isn't a PointerType but a %s, wtf?" format(arrLit toString(), type toString())) throw()

current app("("). app(arrLit getType() as PointerType inner). app("[]) { ")
current app("(")
if(type as PointerType inner instanceOf?(ArrayType)) {
//Nested array, sub-array is always of Array type
current app("_lang_array__Array")
} else {
current app(type as PointerType inner)
}
current app("[]) { ")

isFirst := true
for(element in arrLit elements) {
if(!isFirst) current app(", ")
Expand All @@ -303,10 +311,10 @@ CGenerator: class extends Skeleton {
}

visitArrayCreation: func (node: ArrayCreation) {
writeArrayCreation(node arrayType, node expr, node generateTempName("arrayCrea"))
writeArrayCreation(node arrayType, node expr, node generateTempName("arrayCrea"), !node literal?)
}

writeArrayCreation: func (arrayType: ArrayType, expr: Expression, name: String) {
writeArrayCreation: func (arrayType: ArrayType, expr: Expression, name: String, writeForLoop?: Bool) {
current app("_lang_array__Array_new(")
if(arrayType inner instanceOf?(ArrayType)) {
// otherwise, something like _lang_core__Bool[rows] is written
Expand All @@ -319,14 +327,14 @@ CGenerator: class extends Skeleton {
}
current app(", "). app(arrayType expr). app(")")

if(arrayType inner instanceOf?(ArrayType)) {
if(writeForLoop? && arrayType inner instanceOf?(ArrayType)) {
current app(';'). nl(). app("{"). tab(). nl(). app("int "). app(name). app("__i;"). nl().
app("for("). app(name). app("__i = 0; ").
app(name). app("__i < "). app(arrayType expr). app("; ").
app(name). app("__i++) { "). tab(). nl()

current app("_lang_array__Array "). app(name). app("_sub = ")
writeArrayCreation(arrayType inner as ArrayType, null, name + "_sub")
writeArrayCreation(arrayType inner as ArrayType, null, name + "_sub", true)

current app(";"). nl(). app("_lang_array__Array_set(")
if(expr) {
Expand Down
5 changes: 5 additions & 0 deletions source/rock/middle/ArrayCreation.ooc
Expand Up @@ -5,8 +5,13 @@ import tinker/[Trail, Resolver, Response]
ArrayCreation: class extends Expression {

expr: Expression = null /* assigned in ArrayAccess, RTFC */
literal? := false // used to signify this array is created by a literal and skip some code generation
arrayType, realType : ArrayType

init: func ~withLiteral?(.arrayType, =literal?, .token) {
init(arrayType, token)
}

init: func ~arrayCrea(=arrayType, .token) {
super(token)
realType = arrayType exprLessClone()
Expand Down
4 changes: 2 additions & 2 deletions source/rock/middle/ArrayLiteral.ooc
Expand Up @@ -223,8 +223,8 @@ ArrayLiteral: class extends Literal {
}

vDecl setType(null)
vDecl setExpr(ArrayCreation new(type as ArrayType, token))
ptrDecl := VariableDecl new(null, generateTempName("ptrLit"), this, token)
vDecl setExpr(ArrayCreation new(type as ArrayType, true, token))
ptrDecl := VariableDecl new(arrType inner instanceOf?(ArrayType) ? PointerType new(arrType exprLessClone(), token) : null, generateTempName("ptrLit"), this, token)

// add memcpy from C-pointer literal block
block := Block new(token)
Expand Down
26 changes: 25 additions & 1 deletion source/rock/middle/CoverDecl.ooc
Expand Up @@ -2,7 +2,7 @@ import structs/[HashMap, ArrayList]
import ../io/TabbedWriter
import ../frontend/[Token, BuildParams]
import Expression, Type, Visitor, TypeDecl, Node, FunctionDecl,
FunctionCall
FunctionCall, VariableAccess
import tinker/[Response, Resolver, Trail, Errors]

CoverDecl: class extends TypeDecl {
Expand Down Expand Up @@ -52,6 +52,30 @@ CoverDecl: class extends TypeDecl {
return Response OK
}

resolveCallInFromType: func (call: FunctionCall, res: Resolver, trail: Trail) -> Int {
if(fromType && fromType getRef() && fromType getRef() instanceOf?(TypeDecl)) {

tDecl := fromType getRef() as TypeDecl
meta := tDecl getMeta()
if(meta) {
meta resolveCall(call, res, trail)
} else {
tDecl resolveCall(call, res, trail)
}

} else {
-1
}
}

resolveAccessInFromType: func (access: VariableAccess, res: Resolver, trail: Trail) -> Int {
if(fromType && fromType getRef() && fromType getRef() instanceOf?(TypeDecl)) {
fromType getRef() as TypeDecl resolveAccess(access, res, trail)
} else {
-1
}
}

writeSize: func (w: TabbedWriter, instance: Bool) {
w app("sizeof("). app(underName()). app(")")
}
Expand Down
5 changes: 5 additions & 0 deletions source/rock/middle/FunctionCall.ooc
Expand Up @@ -369,6 +369,11 @@ FunctionCall: class extends Expression {
} else {
tDecl resolveCall(this, res, trail)
}

// If we still haven't got a match for the function and the expression is a cover, we try to look into the cover's "from type"
if(!getRef() && tDecl instanceOf?(CoverDecl)) {
tDecl as CoverDecl resolveCallInFromType(this, res, trail)
}
}
}
}
Expand Down
29 changes: 23 additions & 6 deletions source/rock/middle/Type.ooc
Expand Up @@ -254,9 +254,10 @@ SugarType: abstract class extends Type {
return scoreSeed / 2
}

if(pointerLevel() == 1 && other isPointer()) {
// void pointer, a half match!
return scoreSeed / 2
if(pointerLevel() >= 1 && other isPointer()) {
// void pointer, a partial match!
// The more levels our pointer is, the less of a match we found! :D
return scoreSeed / (2 * pointerLevel())
}

if(other getRef() instanceOf?(CoverDecl)) {
Expand Down Expand Up @@ -304,7 +305,8 @@ PointerType: class extends SugarType {
isPointer: func -> Bool { inner pointerLevel() == 0 && inner void? }

write: func (w: AwesomeWriter, name: String) {
inner write(w, null)
if(inner instanceOf?(ArrayType)) inner as ArrayType write(w, null, true)
else inner write(w, null)
if(!inner isGeneric()) w app('*')
if(name != null) w app(' '). app(name)
}
Expand Down Expand Up @@ -355,21 +357,36 @@ ArrayType: class extends PointerType {
return This NOLUCK_SCORE
}

write: func (w: AwesomeWriter, name: String) {
write: func~_true(w: AwesomeWriter, name: String, forceStars?: Bool) {
if(expr == null) {
w app("_lang_array__Array")
if(name != null) {
w app(' '). app(name)
}
} else if(forceStars?) {
//Nested array declaration
base := inner
while(base instanceOf?(This)) {
base = base as This inner
}
base write(w, null)
stars := ""
pointerLevel() times(|| stars = stars append('*'))
w app(stars)
if(name) w app(' ') . app(name)
} else {
inner write(w, null)
w app(' ')
if(name) w app(name)
if(expr) w app('['). app(expr). app(']')
else w app('*')
else w app('*')
}
}

write: func (w: AwesomeWriter, name: String) {
write~_true(w, name, false)
}

resolve: func (trail: Trail, res: Resolver) -> Response {
if(!This realType resolve(trail, res) ok()) {
return Response LOOP
Expand Down
7 changes: 6 additions & 1 deletion source/rock/middle/VariableAccess.ooc
Expand Up @@ -3,7 +3,7 @@ import BinaryOp, Visitor, Expression, VariableDecl, FunctionDecl,
TypeDecl, Declaration, Type, Node, ClassDecl, NamespaceDecl,
EnumDecl, PropertyDecl, FunctionCall, Module, Import, FuncType,
NullLiteral, AddressOf, BaseType, StructLiteral, Return,
Argument, Scope
Argument, Scope, CoverDecl

import tinker/[Resolver, Response, Trail, Errors]
import structs/ArrayList
Expand Down Expand Up @@ -180,6 +180,11 @@ VariableAccess: class extends Expression {
return Response OK
}
typeDecl resolveAccess(this, res, trail)

//If we did'nt get the ref, we try to get it from the cover's "from type"
if(!ref && typeDecl instanceOf?(CoverDecl)) {
typeDecl as CoverDecl resolveAccessInFromType(this, res, trail)
}
}
}

Expand Down

0 comments on commit 13135e0

Please sign in to comment.