/src/org/ooc/backend/cdirty/MemberAccessWriter.java

http://github.com/nddrylliog/ooc · Java · 103 lines · 82 code · 19 blank · 2 comment · 16 complexity · d7e7a6faa5fbda19e3f854c639e5c2be MD5 · raw file

  1. package org.ooc.backend.cdirty;
  2. import java.io.IOException;
  3. import org.ooc.frontend.model.ClassDecl;
  4. import org.ooc.frontend.model.Dereference;
  5. import org.ooc.frontend.model.Expression;
  6. import org.ooc.frontend.model.FunctionDecl;
  7. import org.ooc.frontend.model.MemberAccess;
  8. import org.ooc.frontend.model.PotentiallyStatic;
  9. import org.ooc.frontend.model.Type;
  10. import org.ooc.frontend.model.TypeDecl;
  11. import org.ooc.frontend.model.VariableAccess;
  12. public class MemberAccessWriter {
  13. public static void write(MemberAccess memberAccess, boolean doTypeParams, CGenerator cgen, int refOffset) throws IOException {
  14. // Allows to do things like "if(T == Int)"
  15. if(memberAccess.getExpression() instanceof VariableAccess) {
  16. VariableAccess varAcc = (VariableAccess) memberAccess.getExpression();
  17. if(varAcc.getRef() instanceof TypeDecl) {
  18. if(memberAccess.getName().equals("class")) {
  19. cgen.current.app(varAcc.getUnderName()).app("_class()");
  20. return;
  21. }
  22. }
  23. }
  24. // duplicated code with LocalAccessWriter: modularize!
  25. int refLevel = memberAccess.getRef().getType().getReferenceLevel();
  26. refLevel += refOffset;
  27. TypeDecl refTypeDecl = memberAccess.getRef().getTypeDecl();
  28. boolean isStatic = ((PotentiallyStatic) memberAccess.getRef()).isStatic();
  29. if(memberAccess.getRef() instanceof FunctionDecl) {
  30. writeFuncAccess(memberAccess, cgen);
  31. return;
  32. }
  33. if(refLevel > 0) {
  34. cgen.current.app('(');
  35. for(int i = 0; i < refLevel; i++) {
  36. cgen.current.app('*');
  37. }
  38. }
  39. if(isStatic) {
  40. if(memberAccess.getRef().isExternWithName()) {
  41. cgen.current.app(memberAccess.getRef().getExternName());
  42. if(refLevel > 0) cgen.current.app(')');
  43. return;
  44. }
  45. cgen.current.app("((").app(refTypeDecl.getType().getUnderName())
  46. .app("Class*) ").app(refTypeDecl.getType().getUnderName())
  47. .app("_class())->").app(memberAccess.getName());
  48. } else {
  49. boolean isArrow = (refTypeDecl instanceof ClassDecl);
  50. boolean didDeref = false;
  51. Expression expression = memberAccess.getExpression();
  52. if(!isArrow && expression instanceof Dereference) {
  53. Dereference deref = (Dereference) expression;
  54. expression = deref.getExpression();
  55. isArrow = true;
  56. didDeref = true;
  57. }
  58. if(refTypeDecl.getType().equals(expression.getType())) {
  59. expression.accept(cgen);
  60. } else {
  61. cgen.current.app("((");
  62. cgen.current.app(((TypeDecl) refTypeDecl.getInstanceType().getRef()).getUnderName());
  63. Type membExprType = memberAccess.getExpression().getType();
  64. TypeWriter.writeFinale(membExprType, cgen);
  65. if(didDeref) cgen.current.app("*");
  66. cgen.current.app(") ");
  67. expression.accept(cgen);
  68. cgen.current.app(')');
  69. }
  70. cgen.current.app(isArrow ? "->" : ".");
  71. LocalAccessWriter.write(memberAccess, false, cgen);
  72. if(refLevel > 0) cgen.current.app(')');
  73. }
  74. }
  75. private static void writeFuncAccess(MemberAccess memberAccess,
  76. CGenerator cgen) throws IOException {
  77. FunctionDecl funcDecl = (FunctionDecl) memberAccess.getRef();
  78. TypeDecl typeDecl = funcDecl.getTypeDecl();
  79. String typeName = typeDecl.getUnderName();
  80. cgen.current.app("((").app(typeName).app("Class *) ");
  81. memberAccess.getExpression().accept(cgen);
  82. cgen.current.app(")->").app(memberAccess.getName());
  83. }
  84. }