Opened 10 years ago
Last modified 10 years ago
#2804 new defect
codegen error if one is using Modelica.Utilities.Streams.readLine
Reported by: | Willi Braun | Owned by: | Lennart Ochel |
---|---|---|---|
Priority: | high | Milestone: | Future |
Component: | Code Generation | Version: | trunk |
Keywords: | Cc: | Martin Sjölund, Mahder Alemseged Gebremedhin, Lennart Ochel |
Description
Models that try to use the function Modelica.Utilities.Streams.readLine are failing with a code generation error.
model test /* function readL input String fileName; input Integer line; output String string; algorithm string := Modelica.Utilities.Streams.readLine(fileName, line); end readL; function readF input String fileName; output String stringVector[Modelica.Utilities.Streams.countLines(fileName)]; algorithm for i in 1:size(stringVector, 1) loop stringVector[i] := readL(fileName, i); end for; Modelica.Utilities.Streams.close(fileName); end readF; */ parameter String fileName = \"./test.txt\"; parameter Integer N = Modelica.Utilities.Streams.countLines(fileName); parameter String file[N] = Modelica.Utilities.Streams.readFile(fileName); // works // parameter String file[N] = readF(fileName); end test;
Somehow the types of an array inside of DAE.STMT_TUPLE_ASSIGN are not generate correct. That code the is generated with the following line works, but then we get other issue. The question is which type should passed to the function contextArrayReferenceCrefAndCopy.
-
Compiler/Template/CodegenC.tpl
4734 4736 match ty 4735 4737 case T_ARRAY(__) then 4736 4738 let &varCopyAfter = buffer "" 4737 let var = tempDecl( "base_array_t", &varDecls)4739 let var = tempDecl(expTypeArrayIf(ty), &varDecls) 4738 4740 let lhs = writeLhsCref(e, var, context, &varCopyAfter, &varDecls, &auxFunction) 4739 4741 let &varCopy += if lhs then '<%lhs%><%\n%>' else error(sourceInfo(), 'Got empty statement from writeLhsCref(<%printExpStr(e)%>)') 4740 4742 let &varCopy += varCopyAfter … … 7070 7081 case STMT_TUPLE_ASSIGN(exp=CALL(attr=CALL_ATTR(ty=T_TUPLE(tupleType=ntys)))) then 7071 7082 let &preExp = buffer "" 7072 7083 let &postExp = buffer "" 7073 7084 let lhsCrefs = (List.rest(expExpLst) |> e => match e 7074 7085 case ARRAY(array={}) 7075 7086 case CREF(componentRef=WILD(__)) then ", NULL" 7076 case CREF(componentRef=cr,ty=ty) then (", &" + contextArrayReferenceCrefAndCopy(cr, e, ty, context, varDecls, postExp, &auxFunction))7087 case CREF(componentRef=cr,ty=ty) then (", &" + contextArrayReferenceCrefAndCopy(cr, e, crefLastType(cr), context, varDecls, postExp, &auxFunction)) 7077 7088 // Crazy DAE.CALL on lhs? Yup, we apparently generate those. TODO: Don't generate those crazy things! 7078 7089 case CALL(attr=CALL_ATTR(ty=ty)) then (", &" + contextArrayReferenceCrefAndCopy(makeUntypedCrefIdent("#error"), e, ty, context, varDecls, postExp, auxFunction)) 7079 7090 else error(sourceInfo(), 'Unknown expression to assign to: <%printExpStr(e)%>')) 7080 7091 // The tuple expressions might take fewer variables than the number of outputs. No worries. 7081 7092 let lhsCrefs2 = lhsCrefs + List.fill(", NULL", intMax(0,intSub(listLength(ntys),listLength(expExpLst)))) 7082 7093 let ret = daeExpCallTuple(exp, lhsCrefs2, context, &preExp, &varDecls, &auxFunction) 7083 7094 let &preExp += match expExpLst 7084 7095 case ARRAY(array={})::_ 7085 7096 case CREF(componentRef=WILD(__))::_ then '<%ret%>;<%\n%>' 7086 case (e as CREF(componentRef=cr,ty=ty))::_ then '<%contextArrayReferenceCrefAndCopy(cr, e, ty, context, varDecls, postExp, auxFunction)%> = <%ret%>;<%\n%>'7097 case (e as CREF(componentRef=cr,ty=ty))::_ then '<%contextArrayReferenceCrefAndCopy(cr, e, crefLastType(cr), context, varDecls, postExp, auxFunction)%> = <%ret%>;<%\n%>' 7087 7098 // Crazy DAE.CALL on lhs? Yup, we apparently generate those. TODO: Don't generate those crazy things! 7088 7099 case (e as CALL(attr=CALL_ATTR(ty=ty)))::_ then '<%contextArrayReferenceCrefAndCopy(makeUntypedCrefIdent("#error"), e, ty, context, varDecls, postExp, auxFunction)%> = <%ret%>;<%\n%>' 7089 7100 case e::_ then error(sourceInfo(), 'Unknown expression to assign to: <%printExpStr(e)%>') 7090 7101 ('/* tuple assignment */<%\n%>' + preExp + postExp) 7091 7102 case STMT_TUPLE_ASSIGN(exp=MATCHEXPRESSION(__)) then 7092 7103 let &preExp = buffer "" 7093 7104 let &afterExp = buffer ""
Change History (6)
comment:1 by , 10 years ago
Cc: | added |
---|
comment:2 by , 10 years ago
comment:3 by , 10 years ago
I also played with crefTypeConsiderSubs(cr) but also without luck.
Do you have ideas how to solve the the underlying problem at all?
Otherwise your working copy would help users anyway.
comment:4 by , 10 years ago
I am just having one problem before I can commit: a function that should not be inlined suddenly is...
Instead of:
C[1,1] = (inv({{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}) * {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}})[1, 1]
I get:
C[1,1] = (LAPACK.dgetri(LU, pivots)[1] * {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}})[1, 1]
But LU and pivots are local variables from the function. And the types on them are wrong, so the array can not be created.
comment:5 by , 10 years ago
I will be busy writing Modrio documents for some time. I could give the code to someone if they want to play with it.
comment:6 by , 10 years ago
In the model above I found a solution that works for now for the user, so I think it's not that urgent.
I believe my working copy will solve the model. But it won't solve the underlying problem that tuple statements assigning to arrays sometimes fail (the fix optimizes the tuple assignment into a regular assignment).
Changing to crefLastType(cr) does not take subscripts into account. Maybe that was the problem.