@Override public DataType visitFactor(@NotNull PythonParser.FactorContext ctx) { if (ctx.power() != null) { return visitPower(ctx.power()); } else if (ctx.factor() != null) { DataType type = visitFactor(ctx.factor()); if (type.isInteger()) { if (ctx.PLUS() != null) { return type; } else if (ctx.MINUS() != null) { mv.visitInsn(INEG); return type; } } else if (type.isBoolean()) { if (ctx.PLUS() != null) { return type; } else if (ctx.MINUS() != null) { mv.visitInsn(INEG); return PrimitiveType.INTEGER; } } else { if (ctx.PLUS() != null) { throw new CompileException( String.format("Doing %s with %s is making no sense!", ctx.PLUS().getText(), type)); } else if (ctx.MINUS() != null) { throw new CompileException( String.format("Doing %s with %s is making no sense!", ctx.MINUS().getText(), type)); } } } throw new CompileException( String.format( "Something gone wrong! Please write to [email protected] with example test.")); }
@Override public DataType visitAtom(@NotNull PythonParser.AtomContext ctx) { // System.out.println("Zz" + ctx.NAME() + ctx.STRING()); if (ctx.test() != null) { // 1 return visitTest(ctx.test()); } else if (ctx.STRING().size() > 0) { // 7,8,9 String ss = ""; for (TerminalNode s : ctx.STRING()) { ss += s.getText(); } mv.visitLdcInsn(ss.length()); mv.visitIntInsn(NEWARRAY, T_CHAR); int tempIndex = 0; for (int i = 0; i < ss.length(); i++) { if (!("\"".equals(ss.substring(i, i + 1))) && !("\'".equals(ss.substring(i, i + 1)))) { mv.visitInsn(DUP); mv.visitLdcInsn(tempIndex); mv.visitLdcInsn(ss.charAt(i)); mv.visitInsn(CASTORE); tempIndex++; } } if (ctx.LBRACK() != null) { if (Integer.parseInt(ctx.INT().getText()) > tempIndex - 1) { throw new CompileException( String.format( "Index out of bounds exception for string %s with index %s", ss, Integer.parseInt(ctx.INT().getText()))); } mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); return new StringType(1); } else { mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "([C)Ljava/lang/String;", false); return new StringType(ss.length()); } } else if (!ctx.NAME().isEmpty()) { // 3,4,5 DataType type = null; // System.out.println("GG" + ctx.getText() + "GG"); String varName = ctx.NAME().get(0).getText(); if (scope.isLocalVariable(varName)) { if (ctx.LBRACK() != null) { // 4,5 type = scope.getLocalVariableType(varName); if (!(type instanceof StringType)) { throw new CompileException(String.format("Trying to take index not from string!!")); } mv.visitVarInsn(type.isPrimitive() ? ILOAD : ALOAD, scope.getLocalVariableIndex(varName)); if (ctx.INT() != null) { mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); if (Integer.parseInt(ctx.INT().getText()) > type.getSize()) { throw new CompileException(String.format("Index out of bounds exception!")); } mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); return new StringType(1); } else if (ctx.NAME(1) != null) { varName = ctx.NAME(1).getText(); type = scope.getLocalVariableType(ctx.NAME(1).getText()); if (!type.isInteger()) { throw new CompileException( String.format("Trying to take index from string not with int!")); } else { Label okLabel = new Label(); mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); mv.visitVarInsn(ILOAD, scope.getLocalVariableIndex(ctx.NAME(1).getText())); mv.visitInsn(DUP); mv.visitLdcInsn(type.getSize()); mv.visitInsn(SWAP); mv.visitJumpInsn(IF_ICMPGT, okLabel); mv.visitLabel(okLabel); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); // TODO out of bounds a[b] // mv.visitLdcInsn("Out of bounds!"); // mv.visitMethodInsn(INVOKESPECIAL, // "java/lang/CompilerException", "<init>", // "(Ljava/lang/String;)V", false); return new StringType(1); } } else { throw new CompileException(String.format("Unidentified operation")); } } else { // 3 type = scope.getLocalVariableType(varName); mv.visitVarInsn(type.isPrimitive() ? ILOAD : ALOAD, scope.getLocalVariableIndex(varName)); } } else if (scope.isGlobalVariable(varName)) { if (ctx.LBRACK() != null) { // 4,5 type = scope.getGlobalVariableType(varName); if (!(type instanceof StringType)) { throw new CompileException(String.format("Trying to take index not from string!!")); } mv.visitFieldInsn( GETSTATIC, scope.getClassName(), varName, type.getType().getDescriptor()); if (ctx.INT() != null) { mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); if (Integer.parseInt(ctx.INT().getText()) > type.getSize()) { throw new CompileException(String.format("Index out of bounds exception!")); } mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); return new StringType(1); } else if (ctx.NAME(1) != null) { varName = ctx.NAME(1).getText(); type = scope.getLocalVariableType(ctx.NAME(1).getText()); if (!type.isInteger()) { throw new CompileException( String.format("Trying to take index from string not with int!")); } else { Label okLabel = new Label(); mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); mv.visitVarInsn(ILOAD, scope.getLocalVariableIndex(ctx.NAME(1).getText())); mv.visitInsn(DUP); mv.visitLdcInsn(type.getSize()); mv.visitInsn(SWAP); mv.visitJumpInsn(IF_ICMPGT, okLabel); mv.visitLabel(okLabel); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); // TODO out of bounds a[b] // mv.visitLdcInsn("Out of bounds!"); // mv.visitMethodInsn(INVOKESPECIAL, // "java/lang/CompilerException", "<init>", // "(Ljava/lang/String;)V", false); return new StringType(1); } } else { throw new CompileException(String.format("Unidentified operation")); } } else { // 3 type = scope.getGlobalVariableType(varName); mv.visitFieldInsn( GETSTATIC, scope.getClassName(), varName, type.getType().getDescriptor()); } } return type; // } else if (scope.isFunction) } else if (ctx.INT() != null) { // 6 mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); return PrimitiveType.INTEGER; } else if (ctx.BOOL() != null) { // 2 mv.visitInsn("False".equals(ctx.BOOL().getText()) ? ICONST_0 : ICONST_1); return PrimitiveType.BOOLEAN; } else { throw new CompileException(String.format("Undefined thing to work with! %s", ctx.getText())); } }