Permalink
Browse files

Merge pull request #468 from shamanas/strInterp

Master ports: nested arrays fix, accessing covered methods and fields without a cast
  • Loading branch information...
alexnask committed Nov 12, 2012
2 parents 1113b21 + 13135e0 commit 36c33082b80a82a9f368ba3f420bf200c87eeeab
@@ -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(", ")
@@ -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
@@ -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) {
@@ -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()
@@ -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)
@@ -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 {
@@ -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(")")
}
@@ -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)
+ }
}
}
}
@@ -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)) {
@@ -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)
}
@@ -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
@@ -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
@@ -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)
+ }
}
}

0 comments on commit 36c3308

Please sign in to comment.