Initial commit

master
github-classroom[bot] 3 years ago
commit 54e35e2b89

149
.gitignore vendored

@ -0,0 +1,149 @@
.DS_Store
__pycache__
target
# Created by https://www.gitignore.io/api/java,eclipse,intellij,emacs,vim
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Emacs ###
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
### Vim ###
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
*.un~
Session.vim
.netrwhist
*~

@ -0,0 +1,26 @@
Copyright (c) 2017-2018 The Regents of the University of California
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,24 @@
# NYU Compiler Construction CSCI-GA.2130/Spring 2021: Programming Assignment 1
This assignment is adapted from https://github.com/cs164berkeley/pa1-chocopy-parser/ with the authors' permission.
See the PA1 document on Piazza for a detailed specification.
## Quickstart
Run the following commands to generate and compile your parser and run the tests:
```
mvn clean package
java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy \
--pass=s --test --dir src/test/data/pa1/sample/
```
`--pass=s` uses your parser (`s` for `student`), and with the starter code, only one test should pass.
`--pass=r` uses the reference parser (`r` for `reference`), which should pass all tests.
In addition to running in test mode with `--test`, you can also observe the actual output
of your (or reference) parser with:
```
java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy \
--pass=s src/test/data/pa1/sample/expr_plus.py
```

Binary file not shown.

@ -0,0 +1,330 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>chocopy</groupId>
<artifactId>chocopy</artifactId>
<packaging>jar</packaging>
<version>2.2-SNAPSHOT</version>
<name>chocopy</name>
<url>http://maven.apache.org</url>
<!-- Set this property to true on the command-line for very verbose output -->
<properties>
<chocopy.debug>false</chocopy.debug>
</properties>
<build>
<!-- Specify JFlex and CUP plugins here; execute in profiles -->
<pluginManagement>
<plugins>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>jflex-maven-plugin</artifactId>
<version>1.6.1</version>
</plugin>
<plugin>
<groupId>com.github.vbmacher</groupId>
<artifactId>cup-maven-plugin</artifactId>
<version>11b-20160615</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>assignment</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<encoding>UTF-8</encoding>
<source>1.8</source>
<target>1.8</target>
<parameters>true</parameters>
<debug>true</debug>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/asm</directory>
<includes>
<include>**/*.s</include>
<include>**/*.os</include>
</includes>
<excludes>
<exclude>**/reference/*.s</exclude>
</excludes>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>reference</id>
<activation>
<!-- This profile is activated whenever we have the reference sources available -->
<file>
<exists>src/main/java/chocopy/reference/</exists>
</file>
</activation>
<build>
<plugins>
<!-- Do not include student skeletons in the reference JAR -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/pa1/*</exclude>
<exclude>**/pa2/*</exclude>
<exclude>**/pa3/*</exclude>
</excludes>
</configuration>
</plugin>
<!-- Name the generated JAR differently so that it is different from the student version -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>chocopy-ref</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
<!-- Run JFlex to generate reference lexer -->
<plugin>
<groupId>de.jflex</groupId>
<artifactId>jflex-maven-plugin</artifactId>
<executions>
<execution>
<id>jflex-reference</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<lexDefinitions>
<lexDefinition>src/main/jflex/chocopy/reference/ChocoPy.jflex</lexDefinition>
</lexDefinitions>
<dump>${chocopy.debug}</dump>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
<!-- Run CUP to generate reference parser -->
<plugin>
<groupId>com.github.vbmacher</groupId>
<artifactId>cup-maven-plugin</artifactId>
<executions>
<execution>
<id>cup-reference</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<cupDefinition>src/main/cup/chocopy/reference/ChocoPy.cup</cupDefinition>
<packageName>chocopy.reference</packageName>
<className>ChocoPyParser</className>
<symbolsName>ChocoPyTokens</symbolsName>
<dumpTables>${chocopy.debug}</dumpTables>
<dumpStates>${chocopy.debug}</dumpStates>
<dumpGrammar>${chocopy.debug}</dumpGrammar>
<locations>true</locations>
</configuration>
</execution>
</executions>
</plugin>
<!-- No debug -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<debug>true</debug>
<debuglevel>none</debuglevel>
</configuration>
</plugin>
<!-- Copy dependencies to target/ -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>pa1</id>
<activation>
<!-- This profile is activated whenever we are in a PA1 distribution -->
<file>
<exists>src/main/java/chocopy/pa1</exists>
</file>
</activation>
<build>
<plugins>
<!-- Run JFlex on the student version -->
<plugin>
<groupId>de.jflex</groupId>
<artifactId>jflex-maven-plugin</artifactId>
<executions>
<execution>
<id>jflex-pa1</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<lexDefinitions>
<lexDefinition>src/main/jflex/chocopy/pa1/ChocoPy.jflex</lexDefinition>
</lexDefinitions>
<dump>${chocopy.debug}</dump>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
<!-- Run CUP on the student version -->
<plugin>
<groupId>com.github.vbmacher</groupId>
<artifactId>cup-maven-plugin</artifactId>
<executions>
<execution>
<id>cup-pa1</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<cupDefinition>src/main/cup/chocopy/pa1/ChocoPy.cup</cupDefinition>
<packageName>chocopy.pa1</packageName>
<className>ChocoPyParser</className>
<symbolsName>ChocoPyTokens</symbolsName>
<dumpTables>${chocopy.debug}</dumpTables>
<dumpStates>${chocopy.debug}</dumpStates>
<dumpGrammar>${chocopy.debug}</dumpGrammar>
<locations>true</locations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>pa2</id>
<activation>
<!-- This profile is activated whenever we are in a PA2 distribution -->
<file>
<exists>src/main/java/chocopy/pa2</exists>
</file>
</activation>
</profile>
<profile>
<id>pa3</id>
<activation>
<!-- This profile is activated whenever we are in a PA3 distribution -->
<file>
<exists>src/main/java/chocopy/pa3</exists>
</file>
</activation>
</profile>
</profiles>
<repositories>
<repository>
<id>venus164-repo</id>
<name>Repository for Venus164</name>
<url>https://raw.githubusercontent.com/chocopy/venus/maven-repository/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.sourceforge.argparse4j</groupId>
<artifactId>argparse4j</artifactId>
<version>0.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>[2.9.10.1,)</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>2.9.10</version>
</dependency>
<dependency>
<groupId>com.github.vbmacher</groupId>
<artifactId>java-cup-runtime</artifactId>
<version>11b-20160615</version>
</dependency>
<!-- https://mvnrepository.com/artifact/de.jflex/jflex -->
<dependency>
<groupId>de.jflex</groupId>
<artifactId>jflex</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.2.71</version>
</dependency>
<dependency>
<groupId>edu.berkeley.eecs.venus164</groupId>
<artifactId>venus164</artifactId>
<version>0.2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>6.0.3</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,214 @@
import java.util.ArrayList;
import java.util.List;
import java_cup.runtime.*;
import chocopy.common.astnodes.*;
/* The following code section is copied verbatim to the generated
* parser class. */
parser code {:
/* The following fields and methods deal with error reporting
* Avoid changing these unless you know what you are doing. */
/** Node that accumulates error messages to be added to the Program
* node produced as a result. */
public final Errors errors = new Errors(new ArrayList<>());
/** Return the Program node that results from parsing the stream of
* tokens produced by lexical analysis. In the case of syntax errors,
* the program may be empty, but will have error messages. */
public Program parseProgram(boolean debug) {
try {
Symbol result = debug ? debug_parse() : parse();
if (result == null || !(result.value instanceof Program)) {
return new Program(new Location(0, 0), new Location(0, 0),
new ArrayList<Declaration>(),
new ArrayList<Stmt>(),
errors);
} else {
return (Program) result.value;
}
} catch (RuntimeException excp) {
throw excp;
} catch (Exception excp) {
String msg =
String.format("Internal parser error detected: %s%n", excp);
throw new AssertionError(msg);
}
}
@Override
public SymbolFactory getSymbolFactory() {
return ((ChocoPyLexer) getScanner()).symbolFactory;
}
@Override
public void syntax_error(Symbol cur_token) {
String token = symbl_name_from_id(cur_token.sym);
String text = ((ChocoPyLexer) getScanner()).yytext();
errors.syntaxError(
((ComplexSymbolFactory.ComplexSymbol) cur_token).xleft,
((ComplexSymbolFactory.ComplexSymbol) cur_token).xright,
"Parse error near token %s: %s", token, text);
}
@Override
public void unrecovered_syntax_error(Symbol cur_token) {
/* Do not die */
}
:}
/**************************************************************************
* FEEL FREE TO MODIFY ANYTHING BELOW THIS LINE
*
* The rules provided below parse expressions of the form <INT> + <INT> + ...
* You can re-use these rules or edit them as you wish. The start rule
* should return a node of type Program.
*
* Tips: Production rules are usually followed by action code that will be
* copied to the generated parser to be executed immediately after a reduce
* operation; that is, when a production rule has been matched. You can name
* a nonterminal or terminal symbol in a production rule using the colon
* notation, e.g. expr_stmt ::= expr:e, to get the AST node for the matched
* expression. In the action code, `e` will be a variable of whatever type
* has been declared for the corresponding nonterminal, such as `Expr`.
* Therefore, you can construct an AST Node of type `ExprStmt` with `e` in the
* constructor: `new ExprStmt(exleft, exright, e)`
*
* The variables `exleft` and `exright` are automatically generated by CUP
* and contain Location objects for the start and end of the expression `e`.
* You can collect start and line number info for AST nodes by taking the
* location of the left end of the leftmost symbol in a rule and the
* location of the right end of the rightmost symbol. The auto-generated
* variables have names `<sym>xleft` and `<sym>xright`, where <sym> is the
* name given to the symbol using the colon notation.
*
* When you have nonterminals that are lists of things, e.g. List<Stmt> or
* List<Declaration>, it is helpful to get the leftmost and rightmost
* source location from within this list; we have provided some utility
* functions below to do just that.
**************************************************************************/
/* The following code section is copied verbatim to the class that performs
* production-rule actions. */
action code {:
/** Return a mutable list initially containing the single value ITEM. */
<T> List<T> single(T item) {
List<T> list = new ArrayList<>();
if (item != null) {
list.add(item);
}
return list;
}
/** If ITEM is non-null, appends it to the end of LIST. Then returns
* LIST. */
<T> List<T> combine(List<T> list, T item) {
if (item != null) {
list.add(item);
}
return list;
}
/** Return a mutable empty list. */
<T> List<T> empty() {
return new ArrayList<T>();
}
/** Return the leftmost non-whitespace location in NODES, or null if NODES
* is empty. Assumes that the nodes of NODES are ordered in increasing
* order of location, from left to right. */
ComplexSymbolFactory.Location getLeft(List<? extends Node> nodes) {
if (nodes.isEmpty()) {
return null;
}
Node first = nodes.get(0);
return new ComplexSymbolFactory.Location(first.getLocation()[0],
first.getLocation()[1]);
}
:}
/* Terminal symbols (tokens returned by the lexer). The declaration
* terminal <identifier1>, <identifier2>, ...;
* declares each <identifieri> as the denotation of a distinct type terminal
* symbol for use in the grammar. The declaration
* terminal <type> <identifier1>, ...;
* does the same, and in addition indicates that the lexer supplies a
* semantic value of type <type> for these symbols that may be referenced
* in actions ( {: ... :} ).
*/
terminal NEWLINE;
terminal String PLUS;
terminal Integer NUMBER;
/* Returned by the lexer for erroneous tokens. Since it does not appear in
* the grammar, it indicates a syntax error. */
terminal UNRECOGNIZED;
/* Nonterminal symbols (defined in production rules below).
* As for terminal symbols,
* non terminal <type> <identifier1>, ..., <identifiern>;
* defines the listed nonterminal identifier symbols to have semantic values
* of type <type>. */
non terminal Program program;
non terminal List<Declaration> program_head;
non terminal List<Stmt> stmt_list, opt_stmt_list;
non terminal Stmt stmt, expr_stmt;
non terminal Expr expr, binary_expr;
/* Precedences (lowest to highest) for resolving what would otherwise be
* ambiguities in the form of shift/reduce conflicts.. */
precedence left PLUS;
/* The start symbol. */
start with program;
/***** GRAMMAR RULES *****/
program ::= program_head:d opt_stmt_list:s
{: RESULT = new Program(d.isEmpty() ? getLeft(s) : getLeft(d),
sxright, d, s, errors);
:}
;
/* Initial list of declarations. */
program_head ::= /* not implemented; currently matches empty string */
{: RESULT = empty(); :}
;
opt_stmt_list ::= {: RESULT = empty(); :}
| stmt_list:s {: RESULT = s; :}
;
stmt_list ::= stmt:s {: RESULT = single(s); :}
| stmt_list:l stmt:s {: RESULT = combine(l, s); :}
| stmt_list:l error {: RESULT = l; :}
/* If there is a syntax error in the source, this says to discard
* symbols from the parsing stack and perform reductions until
* there is a stmt_list on top of the stack, and then to discard
* input symbols until it is possible to shift again, reporting
* a syntax error. */
;
stmt ::= expr_stmt:s NEWLINE {: RESULT = s; :}
;
expr_stmt ::= expr:e {: RESULT = new ExprStmt(exleft, exright, e); :}
;
expr ::= binary_expr:e {: RESULT = e; :}
| NUMBER:n {: RESULT = new IntegerLiteral(nxleft, nxright, n); :}
;
/* A binary expression, illustrating how to find the left and right
* source position of a phrase. */
binary_expr ::= expr:e1 PLUS:op expr:e2
{: RESULT = new BinaryExpr(e1xleft, e2xright,
e1, op, e2); :}
;

@ -0,0 +1,64 @@
package chocopy.common;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
/**
* Utility functions for general use.
*/
public class Utils {
/**
* Return resource file FILENAME's contents as a string. FILENAME
* can refer to a file within the class hierarchy, so that a text
* resource in file resource.txt in the chocopy.common.codegen
* package, for example, could be referred to with FILENAME
* chocopy/common/codegen/resource.txt.
* <p>
* Credit: Lucio Paiva.
*/
public static String getResourceFileAsString(String fileName) {
InputStream is =
Utils.class.getClassLoader().getResourceAsStream(fileName);
if (is != null) {
BufferedReader reader =
new BufferedReader
(new InputStreamReader(is, StandardCharsets.UTF_8));
return reader.lines().collect
(Collectors.joining(System.lineSeparator()));
}
return null;
}
/**
* Return an exception signalling a fatal error having a message
* formed from MSGFORMAT and ARGS, as for String.format.
*/
public static Error fatal(String msgFormat, Object... args) {
return new Error(String.format(msgFormat, args));
}
/**
* Return the string S padded with FILL to TOLEN characters. Padding
* is on the left if PADONLEFT, and otherwise on the right. If S is
* already at least TOLEN characters, returns S.
*/
public static String pad(String s, Character fill, int toLen,
boolean padOnLeft) {
StringBuilder result = new StringBuilder(toLen);
if (!padOnLeft) {
result.append(s);
}
for (int n = s.length(); n < toLen; n += 1) {
result.append(fill);
}
if (padOnLeft) {
result.append(s);
}
return result.toString();
}
}

@ -0,0 +1,100 @@
package chocopy.common.analysis;
import chocopy.common.astnodes.*;
/**
* This interface can be used to separate logic for various concrete
* classes in the AST class hierarchy.
* <p>
* The idea is that a phase of the analysis is encapsulated in a class
* that implements this interface, and contains an overriding of the
* analyze method for each concrete Node class that needs something
* other than default processing. Each concrete node class, C, implements
* a generic dispatch method that takes a NodeAnalyzer<T> argument and
* calls the overloading of analyze that takes an argument of type C.
* The effect is that anode.dispatch(anAnalyzer) executes the method
* anAnalyzer.analyze that is appropriate to aNode's dynamic type.
* As a result each NodeAnalyzer subtype encapsulates all
* implementations of a particular action on Nodes. Thus, it inverts
* the usual OO pattern in which the implementations of analysis A for
* each different class are scattered among the class bodies
* themselves as overridings of a method A on the Node class.
* <p>
* The class AbstractNodeAnalyzer provides empty default
* implementations for these methods.
* <p>
* The type T is the type of result returned by the encapsulated analysis.
*/
public interface NodeAnalyzer<T> {
T analyze(AssignStmt node);
T analyze(BinaryExpr node);
T analyze(BooleanLiteral node);
T analyze(CallExpr node);
T analyze(ClassDef node);
T analyze(ClassType node);
T analyze(CompilerError node);
T analyze(Errors node);
T analyze(ExprStmt node);
T analyze(ForStmt node);
T analyze(FuncDef node);
T analyze(GlobalDecl node);
T analyze(Identifier node);
T analyze(IfExpr node);
T analyze(IfStmt node);
T analyze(IndexExpr node);
T analyze(IntegerLiteral node);
T analyze(ListExpr node);
T analyze(ListType node);
T analyze(MemberExpr node);
T analyze(MethodCallExpr node);
T analyze(NoneLiteral node);
T analyze(NonLocalDecl node);
T analyze(Program node);
T analyze(ReturnStmt node);
T analyze(StringLiteral node);
T analyze(TypedVar node);
T analyze(UnaryExpr node);
T analyze(VarDef node);
T analyze(WhileStmt node);
/**
* Set the default value returned by calls to analyze that are not
* overridden to VALUE. By default, this is null.
*/
void setDefault(T value);
/**
* Default value for non-overridden methods.
*/
T defaultAction(Node node);
}

@ -0,0 +1,36 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* Single and multiple assignments.
*/
public class AssignStmt extends Stmt {
/**
* List of left-hand sides.
*/
public final List<Expr> targets;
/**
* Right-hand-side value to be assigned.
*/
public final Expr value;
/**
* AST for TARGETS[0] = TARGETS[1] = ... = VALUE spanning source locations
* [LEFT..RIGHT].
*/
public AssignStmt(Location left, Location right,
List<Expr> targets, Expr value) {
super(left, right);
this.targets = targets;
this.value = value;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,40 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* <operand> <operator> <operand>.
*/
public class BinaryExpr extends Expr {
/**
* Left operand.
*/
public final Expr left;
/**
* Operator name.
*/
public final String operator;
/**
* Right operand.
*/
public final Expr right;
/**
* An AST for expressions of the form LEFTEXPR OP RIGHTEXPR
* from text in range [LEFTLOC..RIGHTLOC].
*/
public BinaryExpr(Location leftLoc, Location rightLoc, Expr leftExpr,
String op, Expr rightExpr) {
super(leftLoc, rightLoc);
left = leftExpr;
operator = op;
right = rightExpr;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,29 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Literals True or False.
*/
public final class BooleanLiteral extends Literal {
/**
* True iff I represent True.
*/
public final boolean value;
/**
* An AST for the token True or False at [LEFT..RIGHT], depending on
* VALUE.
*/
public BooleanLiteral(Location left, Location right, boolean value) {
super(left, right);
this.value = value;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,36 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* A function call.
*/
public class CallExpr extends Expr {
/**
* The called function.
*/
public final Identifier function;
/**
* The actual parameter expressions.
*/
public final List<Expr> args;
/**
* AST for FUNCTION(ARGS) at [LEFT..RIGHT].
*/
public CallExpr(Location left, Location right, Identifier function,
List<Expr> args) {
super(left, right);
this.function = function;
this.args = args;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,50 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* A class definition.
*/
public class ClassDef extends Declaration {
/**
* Name of the declared class.
*/
public final Identifier name;
/**
* Name of the parent class.
*/
public final Identifier superClass;
/**
* Body of the class.
*/
public final List<Declaration> declarations;
/**
* An AST for class
* NAME(SUPERCLASS):
* DECLARATIONS.
* spanning source locations [LEFT..RIGHT].
*/
public ClassDef(Location left, Location right,
Identifier name, Identifier superClass,
List<Declaration> declarations) {
super(left, right);
this.name = name;
this.superClass = superClass;
this.declarations = declarations;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
@Override
public Identifier getIdentifier() {
return this.name;
}
}

@ -0,0 +1,28 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* A simple class type name.
*/
public final class ClassType extends TypeAnnotation {
/**
* The denotation of the class in source.
*/
public final String className;
/**
* An AST denoting a type named CLASSNAME0 at [LEFT..RIGHT].
*/
public ClassType(Location left, Location right, String className0) {
super(left, right);
className = className0;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,64 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import com.fasterxml.jackson.annotation.JsonInclude;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.Arrays;
import java.util.Objects;
/**
* Represents a single error. Does not correspond to any Python source
* construct.
*/
public class CompilerError extends Node {
/**
* Represents an error with message MESSAGE. Iff SYNTAX, it is a
* syntactic error. The error applies to source text at [LEFT..RIGHT].
*/
public CompilerError(Location left, Location right, String message,
boolean syntax) {
super(left, right);
this.message = message;
this.syntax = syntax;
}
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public boolean isSyntax() {
return syntax;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CompilerError that = (CompilerError) o;
return Objects.equals(message, that.message)
&& Arrays.equals(getLocation(), that.getLocation());
}
@Override
public int hashCode() {
int result = Objects.hash(message);
result = 31 * result + Arrays.hashCode(getLocation());
return result;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
/**
* The error message.
*/
public final String message;
/**
* True if this is a syntax error.
*/
private final boolean syntax;
}

@ -0,0 +1,23 @@
package chocopy.common.astnodes;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Base of all AST nodes representing definitions or declarations.
*/
public abstract class Declaration extends Node {
/**
* A definition or declaration spanning source locations [LEFT..RIGHT].
*/
public Declaration(Location left, Location right) {
super(left, right);
}
/**
* Return the identifier defined by this Declaration.
*/
@JsonIgnore
public abstract Identifier getIdentifier();
}

@ -0,0 +1,90 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* Collects the error messages in a Program. There is exactly one per
* Program node.
*/
public class Errors extends Node {
/**
* The accumulated error messages in the order added.
*/
public final List<CompilerError> errors;
/**
* True iff multiple semantic errors allowed on a node.
*/
@JsonIgnore
private boolean allowMultipleErrors;
/**
* An Errors whose list of CompilerErrors is ERRORS. The list should be
* modified using this.add.
*/
@JsonCreator
public Errors(List<CompilerError> errors) {
super(null, null);
this.errors = errors;
allowMultipleErrors = true;
}
/**
* Return true iff there are any errors.
*/
public boolean hasErrors() {
return !this.errors.isEmpty();
}
/**
* Prevent multiple semantic errors on the same node.
*/
public void suppressMultipleErrors() {
allowMultipleErrors = false;
}
/**
* Add a new semantic error message attributed to NODE, with message
* String.format(MESSAGEFORM, ARGS).
*/
public void semError(Node node, String messageForm, Object... args) {
if (allowMultipleErrors || !node.hasError()) {
String msg = String.format(messageForm, args);
CompilerError err = new CompilerError(null, null, msg, false);
err.setLocation(node.getLocation());
add(err);
if (!node.hasError()) {
node.setErrorMsg(msg);
}
}
}
/**
* Add a new syntax error message attributed to the source text
* between LEFT and RIGHT, and with message
* String.format(MESSAGEFORM, ARGS).
*/
public void syntaxError(Location left, Location right,
String messageForm, Object... args) {
add(new CompilerError(left, right, String.format(messageForm, args),
true));
}
/**
* Add ERR to the list of errors.
*/
public void add(CompilerError err) {
errors.add(err);
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,22 @@
package chocopy.common.astnodes;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Base of all AST nodes representing expressions.
* <p>
* There is nothing in this class, but there will be many AST
* node types that have fields that are *any expression*. For those
* cases, having a field of this type will encompass all types of
* expressions such as binary expressions and literals that subclass
* this class.
*/
public abstract class Expr extends Node {
/**
* A Python expression spanning source locations [LEFT..RIGHT].
*/
public Expr(Location left, Location right) {
super(left, right);
}
}

@ -0,0 +1,29 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Statements consisting of expressions.
*/
public final class ExprStmt extends Stmt {
/**
* The expression I evaluate.
*/
public final Expr expr;
/**
* The AST for EXPR spanning source locations [LEFT..RIGHT]
* in a statement context.
*/
public ExprStmt(Location left, Location right, Expr expr) {
super(left, right);
this.expr = expr;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,43 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* For statements.
*/
public class ForStmt extends Stmt {
/**
* Control variable.
*/
public final Identifier identifier;
/**
* Source of values of control statement.
*/
public final Expr iterable;
/**
* Repeated statements.
*/
public final List<Stmt> body;
/**
* The AST for
* for IDENTIFIER in ITERABLE:
* BODY
* spanning source locations [LEFT..RIGHT].
*/
public ForStmt(Location left, Location right,
Identifier identifier, Expr iterable, List<Stmt> body) {
super(left, right);
this.identifier = identifier;
this.iterable = iterable;
this.body = body;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,61 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* Def statements.
*/
public class FuncDef extends Declaration {
/**
* Defined name.
*/
public final Identifier name;
/**
* Formal parameters.
*/
public final List<TypedVar> params;
/**
* Return type annotation.
*/
public final TypeAnnotation returnType;
/**
* Local-variable,inner-function, global, and nonlocal declarations.
*/
public final List<Declaration> declarations;
/**
* Other statements.
*/
public final List<Stmt> statements;
/**
* The AST for
* def NAME(PARAMS) -> RETURNTYPE:
* DECLARATIONS
* STATEMENTS
* spanning source locations [LEFT..RIGHT].
*/
public FuncDef(Location left, Location right,
Identifier name, List<TypedVar> params,
TypeAnnotation returnType,
List<Declaration> declarations, List<Stmt> statements) {
super(left, right);
this.name = name;
this.params = params;
this.returnType = returnType;
this.declarations = declarations;
this.statements = statements;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
@Override
public Identifier getIdentifier() {
return this.name;
}
}

@ -0,0 +1,34 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Declaration of global variable.
*/
public class GlobalDecl extends Declaration {
/**
* The declared variable.
*/
public final Identifier variable;
/**
* The AST for the declaration
* global VARIABLE
* spanning source locations [LEFT..RIGHT].
*/
public GlobalDecl(Location left, Location right, Identifier variable) {
super(left, right);
this.variable = variable;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
@Override
public Identifier getIdentifier() {
return this.variable;
}
}

@ -0,0 +1,29 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* A simple identifier.
*/
public class Identifier extends Expr {
/**
* Text of the identifier.
*/
public final String name;
/**
* An AST for the variable, method, or parameter named NAME, spanning
* source locations [LEFT..RIGHT].
*/
public Identifier(Location left, Location right, String name) {
super(left, right);
this.name = name;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,40 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Conditional expressions.
*/
public class IfExpr extends Expr {
/**
* Boolean condition.
*/
public final Expr condition;
/**
* True branch.
*/
public final Expr thenExpr;
/**
* False branch.
*/
public final Expr elseExpr;
/**
* The AST for
* THENEXPR if CONDITION else ELSEEXPR
* spanning source locations [LEFT..RIGHT].
*/
public IfExpr(Location left, Location right,
Expr condition, Expr thenExpr, Expr elseExpr) {
super(left, right);
this.condition = condition;
this.thenExpr = thenExpr;
this.elseExpr = elseExpr;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,45 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* Conditional statement.
*/
public class IfStmt extends Stmt {
/**
* Test condition.
*/
public final Expr condition;
/**
* "True" branch.
*/
public final List<Stmt> thenBody;
/**
* "False" branch.
*/
public final List<Stmt> elseBody;
/**
* The AST for
* if CONDITION:
* THENBODY
* else:
* ELSEBODY
* spanning source locations [LEFT..RIGHT].
*/
public IfStmt(Location left, Location right,
Expr condition, List<Stmt> thenBody, List<Stmt> elseBody) {
super(left, right);
this.condition = condition;
this.thenBody = thenBody;
this.elseBody = elseBody;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,35 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* List-indexing expression.
*/
public class IndexExpr extends Expr {
/**
* Indexed list.
*/
public final Expr list;
/**
* Expression for index value.
*/
public final Expr index;
/**
* The AST for
* LIST[INDEX].
* spanning source locations [LEFT..RIGHT].
*/
public IndexExpr(Location left, Location right, Expr list, Expr index) {
super(left, right);
this.list = list;
this.index = index;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,29 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Integer numerals.
*/
public final class IntegerLiteral extends Literal {
/**
* Value denoted.
*/
public final int value;
/**
* The AST for the literal VALUE, spanning source
* locations [LEFT..RIGHT].
*/
public IntegerLiteral(Location left, Location right, int value) {
super(left, right);
this.value = value;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,32 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* List displays.
*/
public final class ListExpr extends Expr {
/**
* List of element expressions.
*/
public final List<Expr> elements;
/**
* The AST for
* [ ELEMENTS ].
* spanning source locations [LEFT..RIGHT].
*/
public ListExpr(Location left, Location right, List<Expr> elements) {
super(left, right);
this.elements = elements;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,30 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Type denotation for a list type.
*/
public final class ListType extends TypeAnnotation {
/**
* The element of list element.
*/
public final TypeAnnotation elementType;
/**
* The AST for the type annotation
* [ ELEMENTTYPE ].
* spanning source locations [LEFT..RIGHT].
*/
public ListType(Location left, Location right, TypeAnnotation elementType) {
super(left, right);
this.elementType = elementType;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,18 @@
package chocopy.common.astnodes;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Base of all the literal nodes.
* <p>
* There is nothing in this class, but it is useful to isolate
* expressions that are constant literals.
*/
public abstract class Literal extends Expr {
/**
* A literal spanning source locations [LEFT..RIGHT].
*/
public Literal(Location left, Location right) {
super(left, right);
}
}

@ -0,0 +1,36 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Attribute accessor.
*/
public class MemberExpr extends Expr {
/**
* Object selected from.
*/
public final Expr object;
/**
* Name of attribute (instance variable or method).
*/
public final Identifier member;
/**
* The AST for
* OBJECT.MEMBER.
* spanning source locations [LEFT..RIGHT].
*/
public MemberExpr(Location left, Location right,
Expr object, Identifier member) {
super(left, right);
this.object = object;
this.member = member;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,38 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* Method calls.
*/
public class MethodCallExpr extends Expr {
/**
* Expression for the bound method to be called.
*/
public final MemberExpr method;
/**
* Actual parameters.
*/
public final List<Expr> args;
/**
* The AST for
* METHOD(ARGS).
* spanning source locations [LEFT..RIGHT].
*/
public MethodCallExpr(Location left, Location right,
MemberExpr method, List<Expr> args) {
super(left, right);
this.method = method;
this.args = args;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,204 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.io.IOException;
/**
* Root of the AST class hierarchy. Every node has a left and right
* location, indicating the start and end of the represented construct
* in the source text.
* <p>
* Every node can be marked with an error message, which serves two purposes:
* 1. It indicates that an error message has been issued for this
* Node, allowing tne program to reduce cascades of error
* messages.
* 2. It aids in debugging by making it convenient to see which
* Nodes have caused an error.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "kind")
/* List of all concrete subclasses of Node. */
@JsonSubTypes({
@JsonSubTypes.Type(AssignStmt.class),
@JsonSubTypes.Type(BinaryExpr.class),
@JsonSubTypes.Type(BooleanLiteral.class),
@JsonSubTypes.Type(CallExpr.class),
@JsonSubTypes.Type(ClassDef.class),
@JsonSubTypes.Type(ClassType.class),
@JsonSubTypes.Type(CompilerError.class),
@JsonSubTypes.Type(Errors.class),
@JsonSubTypes.Type(ExprStmt.class),
@JsonSubTypes.Type(ForStmt.class),
@JsonSubTypes.Type(FuncDef.class),
@JsonSubTypes.Type(GlobalDecl.class),
@JsonSubTypes.Type(Identifier.class),
@JsonSubTypes.Type(IfExpr.class),
@JsonSubTypes.Type(IfStmt.class),
@JsonSubTypes.Type(IndexExpr.class),
@JsonSubTypes.Type(IntegerLiteral.class),
@JsonSubTypes.Type(ListExpr.class),
@JsonSubTypes.Type(ListType.class),
@JsonSubTypes.Type(MemberExpr.class),
@JsonSubTypes.Type(MethodCallExpr.class),
@JsonSubTypes.Type(NoneLiteral.class),
@JsonSubTypes.Type(NonLocalDecl.class),
@JsonSubTypes.Type(Program.class),
@JsonSubTypes.Type(ReturnStmt.class),
@JsonSubTypes.Type(StringLiteral.class),
@JsonSubTypes.Type(TypedVar.class),
@JsonSubTypes.Type(UnaryExpr.class),
@JsonSubTypes.Type(VarDef.class),
@JsonSubTypes.Type(WhileStmt.class),
})
public abstract class Node {
/**
* Node-type indicator for JSON form.
*/
public final String kind;
/**
* Source position information: 0: line number of start, 1: column number
* of start, 2: line number of end, 3: column number of end.
*/
private final int[] location = new int[4];
/**
* First error message "blamed" on this Node. When non-null, indicates
* that an error has been found in this Node.
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String errorMsg;
/**
* A Node corresponding to source text between LEFT and RIGHT.
*/
public Node(Location left, Location right) {
if (left != null) {
location[0] = left.getLine();
location[1] = left.getColumn();
}
if (right != null) {
location[2] = right.getLine();
location[3] = right.getColumn();
}
this.kind = getClass().getSimpleName();
this.errorMsg = null;
}
/**
* Return my source location as
* { <first line>, <first column>, <last line>, <last column> }.
* Result should not be modified, and contents will change after
* setLocation().
*/
public int[] getLocation() {
return location;
}
/**
* Copy LOCATION as getLocation().
*/
public void setLocation(final int[] location) {
System.arraycopy(location, 0, this.location, 0, 4);
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String msg) {
this.errorMsg = msg;
}
/**
* Return true iff I have been marked with an error message.
*/
@JsonIgnore
public boolean hasError() {
return this.errorMsg != null;
}
/**
* Invoke ANALYZER on me as a node of static type T. See the comment
* on NodeAnalyzer. Returns modified Node.
*/
public abstract <T> T dispatch(NodeAnalyzer<T> analyzer);
/**
* Print out the AST in JSON format.
*/
@Override
public String toString() {
try {
return toJSON();
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* Return a serialization of this node in JSON format.
*/
public String toJSON() throws JsonProcessingException {
return mapper.writeValueAsString(this);
}
/**
* Mapper to-and-from serialized JSON.
*/
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(new ParameterNamesModule());
}
/**
* Returns a T from JSON, a JSON-serialized T value with class
* CLAS.
*/
public static <T> T fromJSON(String json, Class<T> clas)
throws IOException {
return mapper.readValue(json, clas);
}
/**
* Returns the result of converting JSON, a JSon-serialization of
* a Node value, into the value it serializes.
*/
public static Node fromJSON(String json)
throws IOException {
return fromJSON(json, Node.class);
}
/**
* Returns the result of converting TREE to the value of type T
* that it represents, where CLAS reflects T.
*/
public static <T> T fromJSON(JsonNode tree, Class<T> clas)
throws IOException {
return mapper.treeToValue(tree, clas);
}
/**
* Returns the translation of serialized value SRC into the
* corresponding JSON tree.
*/
public static JsonNode readTree(String src) throws IOException {
return mapper.readTree(src);
}
}

@ -0,0 +1,34 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Nonlocal declaration.
*/
public class NonLocalDecl extends Declaration {
/**
* Name of identifier being declared.
*/
public final Identifier variable;
/**
* The AST for
* nonlocal VARIABLE
* spanning source locations [LEFT..RIGHT].
*/
public NonLocalDecl(Location left, Location right, Identifier variable) {
super(left, right);
this.variable = variable;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
@Override
public Identifier getIdentifier() {
return this.variable;
}
}

@ -0,0 +1,21 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* The expression 'None'.
*/
public final class NoneLiteral extends Literal {
/**
* The AST for None, spanning source locations [LEFT..RIGHT].
*/
public NoneLiteral(Location left, Location right) {
super(left, right);
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,70 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.ArrayList;
import java.util.List;
/**
* An entire ChocoPy program.
*/
public class Program extends Node {
/**
* Initial variable, class, and function declarations.
*/
public final List<Declaration> declarations;
/**
* Trailing statements.
*/
public final List<Stmt> statements;
/**
* Accumulated errors.
*/
public final Errors errors;
/**
* The AST for the program
* DECLARATIONS
* STATEMENTS
* spanning source locations [LEFT..RIGHT].
* <p>
* ERRORS is the container for all error messages applying to the
* program.
*/
public Program(Location left, Location right,
List<Declaration> declarations, List<Stmt> statements,
Errors errors) {
super(left, right);
this.declarations = declarations;
this.statements = statements;
if (errors == null) {
this.errors = new Errors(new ArrayList<>());
} else {
this.errors = errors;
}
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
/**
* Returns true iff there is at least one error in the program.
*/
@JsonIgnore
public boolean hasErrors() {
return errors.hasErrors();
}
/**
* A convenience method returning the list of all CompilerErrors for
* this program.
*/
@JsonIgnore
public List<CompilerError> getErrorList() {
return errors.errors;
}
}

@ -0,0 +1,30 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Return from function.
*/
public class ReturnStmt extends Stmt {
/**
* Returned value.
*/
public final Expr value;
/**
* The AST for
* return VALUE
* spanning source locations [LEFT..RIGHT].
*/
public ReturnStmt(Location left, Location right, Expr value) {
super(left, right);
this.value = value;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,21 @@
package chocopy.common.astnodes;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Base of all AST nodes representing statements.
* <p>
* There is nothing in this class, but there will be some AST
* node types that have fields that are *any statement* or a
* list of statements. For those cases, having a field of this type will
* encompass all types of statements such as expression statements,
* if statements, while statements, etc.
*/
public abstract class Stmt extends Node {
/**
* A statement spanning source locations [LEFT..RIGHT].
*/
public Stmt(Location left, Location right) {
super(left, right);
}
}

@ -0,0 +1,29 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* String constants.
*/
public final class StringLiteral extends Literal {
/**
* Contents of the literal, not including quotation marks.
*/
public final String value;
/**
* The AST for a string literal containing VALUE, spanning source
* locations [LEFT..RIGHT].
*/
public StringLiteral(Location left, Location right, String value) {
super(left, right);
this.value = value;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,16 @@
package chocopy.common.astnodes;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* Base of all AST nodes representing type annotations (list or class
* types.
*/
public abstract class TypeAnnotation extends Node {
/**
* An annotation spanning source locations [LEFT..RIGHT].
*/
public TypeAnnotation(Location left, Location right) {
super(left, right);
}
}

@ -0,0 +1,36 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* An identifier with attached type annotation.
*/
public class TypedVar extends Node {
/**
* The typed identifier.
*/
public final Identifier identifier;
/**
* The declared type.
*/
public final TypeAnnotation type;
/**
* The AST for
* IDENTIFIER : TYPE.
* spanning source locations [LEFT..RIGHT].
*/
public TypedVar(Location left, Location right,
Identifier identifier, TypeAnnotation type) {
super(left, right);
this.identifier = identifier;
this.type = type;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,36 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* An expression applying a unary operator.
*/
public class UnaryExpr extends Expr {
/**
* The text representation of the operator.
*/
public final String operator;
/**
* The operand to which it is applied.
*/
public final Expr operand;
/**
* The AST for
* OPERATOR OPERAND
* spanning source locations [LEFT..RIGHT].
*/
public UnaryExpr(Location left, Location right,
String operator, Expr operand) {
super(left, right);
this.operator = operator;
this.operand = operand;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,42 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
/**
* A declaration of a variable (i.e., with type annotation).
*/
public class VarDef extends Declaration {
/**
* The variable and its assigned type.
*/
public final TypedVar var;
/**
* The initial value assigned.
*/
public final Literal value;
/**
* The AST for
* VAR = VALUE
* where VAR has a type annotation, and spanning source
* locations [LEFT..RIGHT].
*/
public VarDef(Location left, Location right, TypedVar var, Literal value) {
super(left, right);
this.var = var;
this.value = value;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
/**
* The identifier defined by this declaration.
*/
@Override
public Identifier getIdentifier() {
return this.var.identifier;
}
}

@ -0,0 +1,39 @@
package chocopy.common.astnodes;
import chocopy.common.analysis.NodeAnalyzer;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java.util.List;
/**
* Indefinite repetition construct.
*/
public class WhileStmt extends Stmt {
/**
* Test for whether to continue.
*/
public final Expr condition;
/**
* Loop body.
*/
public final List<Stmt> body;
/**
* The AST for
* while CONDITION:
* BODY
* spanning source locations [LEFT..RIGHT].
*/
public WhileStmt(Location left, Location right,
Expr condition, List<Stmt> body) {
super(left, right);
this.condition = condition;
this.body = body;
}
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
return analyzer.analyze(this);
}
}

@ -0,0 +1,25 @@
package chocopy.pa1;
import chocopy.common.astnodes.Program;
import java_cup.runtime.ComplexSymbolFactory;
import java.io.StringReader;
/**
* Interface between driver and parser.
*/
public class StudentParser {
/**
* Return the Program AST resulting from parsing INPUT. Turn on
* parser debugging iff DEBUG.
*/
public static Program process(String input, boolean debug) {
ChocoPyLexer lexer = new ChocoPyLexer(new StringReader(input));
ChocoPyParser parser =
new ChocoPyParser(lexer, new ComplexSymbolFactory());
return parser.parseProgram(debug);
}
}

@ -0,0 +1,82 @@
package chocopy.pa1;
import java_cup.runtime.*;
%%
/*** Do not change the flags below unless you know what you are doing. ***/
%unicode
%line
%column
%class ChocoPyLexer
%public
%cupsym ChocoPyTokens
%cup
%cupdebug
%eofclose false
/*** Do not change the flags above unless you know what you are doing. ***/
/* The following code section is copied verbatim to the
* generated lexer class. */
%{
/* The code below includes some convenience methods to create tokens
* of a given type and optionally a value that the CUP parser can
* understand. Specifically, a lot of the logic below deals with
* embedded information about where in the source code a given token
* was recognized, so that the parser can report errors accurately.
* (It need not be modified for this project.) */
/** Producer of token-related values for the parser. */
final ComplexSymbolFactory symbolFactory = new ComplexSymbolFactory();
/** Return a terminal symbol of syntactic category TYPE and no
* semantic value at the current source location. */
private Symbol symbol(int type) {
return symbol(type, yytext());
}
/** Return a terminal symbol of syntactic category TYPE and semantic
* value VALUE at the current source location. */
private Symbol symbol(int type, Object value) {
return symbolFactory.newSymbol(ChocoPyTokens.terminalNames[type], type,
new ComplexSymbolFactory.Location(yyline + 1, yycolumn + 1),
new ComplexSymbolFactory.Location(yyline + 1,yycolumn + yylength()),
value);
}
%}
/* Macros (regexes used in rules below) */
WhiteSpace = [ \t]
LineBreak = \r|\n|\r\n
IntegerLiteral = 0 | [1-9][0-9]*
%%
<YYINITIAL> {
/* Delimiters. */
{LineBreak} { return symbol(ChocoPyTokens.NEWLINE); }
/* Literals. */
{IntegerLiteral} { return symbol(ChocoPyTokens.NUMBER,
Integer.parseInt(yytext())); }
/* Operators. */
"+" { return symbol(ChocoPyTokens.PLUS, yytext()); }
/* Whitespace. */
{WhiteSpace} { /* ignore */ }
}
<<EOF>> { return symbol(ChocoPyTokens.EOF); }
/* Error fallback. */
[^] { return symbol(ChocoPyTokens.UNRECOGNIZED); }

@ -0,0 +1,16 @@
{
"kind" : "Program",
"location" : [ 1, 6, 1, 6 ],
"declarations" : [ ],
"statements" : [ ],
"errors" : {
"errors" : [ {
"kind" : "CompilerError",
"location" : [ 1, 8, 1, 8 ],
"message" : "Parse error near token EQ: =",
"syntax" : true
} ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,16 @@
{
"kind" : "Program",
"location" : [ 1, 7, 1, 7 ],
"declarations" : [ ],
"statements" : [ ],
"errors" : {
"errors" : [ {
"kind" : "CompilerError",
"location" : [ 1, 9, 1, 9 ],
"message" : "Parse error near token EQ: =",
"syntax" : true
} ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,6 @@
def foo(a, b) -> 1:
x:int = a
return 1
print(1)
print(3**6)

@ -0,0 +1,64 @@
{
"kind" : "Program",
"location" : [ 2, 13, 6, 8 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 2, 13, 2, 13 ],
"expr" : {
"kind" : "Identifier",
"location" : [ 2, 13, 2, 13 ],
"name" : "a"
}
}, {
"kind" : "ReturnStmt",
"location" : [ 3, 5, 3, 12 ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 12, 3, 12 ],
"value" : 1
}
}, {
"kind" : "ExprStmt",
"location" : [ 5, 1, 5, 8 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 5, 1, 5, 8 ],
"function" : {
"kind" : "Identifier",
"location" : [ 5, 1, 5, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 5, 7, 5, 7 ],
"value" : 1
} ]
}
} ],
"errors" : {
"errors" : [ {
"kind" : "CompilerError",
"location" : [ 1, 10, 1, 10 ],
"message" : "Parse error near token COMMA: ,",
"syntax" : true
}, {
"kind" : "CompilerError",
"location" : [ 2, 13, 2, 13 ],
"message" : "Parse error near token IDENTIFIER: a",
"syntax" : true
}, {
"kind" : "CompilerError",
"location" : [ 5, 1, 5, 0 ],
"message" : "Parse error near token DEDENT: ",
"syntax" : true
}, {
"kind" : "CompilerError",
"location" : [ 6, 9, 6, 9 ],
"message" : "Parse error near token TIMES: *",
"syntax" : true
} ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,47 @@
{
"kind" : "Program",
"location" : [ 2, 3, 3, 6 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 2, 3, 2, 7 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 2, 3, 2, 3 ],
"name" : "y"
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 7, 2, 7 ],
"value" : 2
}
}, {
"kind" : "AssignStmt",
"location" : [ 3, 1, 3, 5 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 3, 1, 3, 1 ],
"name" : "z"
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 5, 3, 5 ],
"value" : 3
}
} ],
"errors" : {
"errors" : [ {
"kind" : "CompilerError",
"location" : [ 2, 1, 2, 2 ],
"message" : "Parse error near token INDENT: ",
"syntax" : true
}, {
"kind" : "CompilerError",
"location" : [ 3, 1, 3, 0 ],
"message" : "Parse error near token DEDENT: ",
"syntax" : true
} ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,4 @@
1 + 2
3 == 4 or (not False && True)
5 + 6
7 << 8

@ -0,0 +1,65 @@
{
"kind" : "Program",
"location" : [ 1, 1, 4, 7 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 5 ],
"expr" : {
"kind" : "BinaryExpr",
"location" : [ 1, 1, 1, 5 ],
"left" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 1, 1, 1 ],
"value" : 1
},
"operator" : "+",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 5, 1, 5 ],
"value" : 2
}
}
}, {
"kind" : "ExprStmt",
"location" : [ 3, 1, 3, 5 ],
"expr" : {
"kind" : "BinaryExpr",
"location" : [ 3, 1, 3, 5 ],
"left" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 1, 3, 1 ],
"value" : 5
},
"operator" : "+",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 5, 3, 5 ],
"value" : 6
}
}
}, {
"kind" : "ExprStmt",
"location" : [ 4, 6, 4, 6 ],
"expr" : {
"kind" : "IntegerLiteral",
"location" : [ 4, 6, 4, 6 ],
"value" : 8
}
} ],
"errors" : {
"errors" : [ {
"kind" : "CompilerError",
"location" : [ 2, 22, 2, 22 ],
"message" : "Parse error near token UNRECOGNIZED: &",
"syntax" : true
}, {
"kind" : "CompilerError",
"location" : [ 4, 4, 4, 4 ],
"message" : "Parse error near token LT: <",
"syntax" : true
} ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,2 @@
x[0] = y = z.f = 1
z.g = y = x[0]

@ -0,0 +1,85 @@
{
"kind" : "Program",
"location" : [ 1, 1, 2, 15 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 1, 1, 1, 18 ],
"targets" : [ {
"kind" : "IndexExpr",
"location" : [ 1, 1, 1, 4 ],
"list" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 1 ],
"name" : "x"
},
"index" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 3, 1, 3 ],
"value" : 0
}
}, {
"kind" : "Identifier",
"location" : [ 1, 8, 1, 8 ],
"name" : "y"
}, {
"kind" : "MemberExpr",
"location" : [ 1, 12, 1, 14 ],
"object" : {
"kind" : "Identifier",
"location" : [ 1, 12, 1, 12 ],
"name" : "z"
},
"member" : {
"kind" : "Identifier",
"location" : [ 1, 14, 1, 14 ],
"name" : "f"
}
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 18, 1, 18 ],
"value" : 1
}
}, {
"kind" : "AssignStmt",
"location" : [ 2, 1, 2, 14 ],
"targets" : [ {
"kind" : "MemberExpr",
"location" : [ 2, 1, 2, 3 ],
"object" : {
"kind" : "Identifier",
"location" : [ 2, 1, 2, 1 ],
"name" : "z"
},
"member" : {
"kind" : "Identifier",
"location" : [ 2, 3, 2, 3 ],
"name" : "g"
}
}, {
"kind" : "Identifier",
"location" : [ 2, 7, 2, 7 ],
"name" : "y"
} ],
"value" : {
"kind" : "IndexExpr",
"location" : [ 2, 11, 2, 14 ],
"list" : {
"kind" : "Identifier",
"location" : [ 2, 11, 2, 11 ],
"name" : "x"
},
"index" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 13, 2, 13 ],
"value" : 0
}
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,32 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 14 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 1, 1, 1, 13 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 1 ],
"name" : "x"
}, {
"kind" : "Identifier",
"location" : [ 1, 5, 1, 5 ],
"name" : "y"
}, {
"kind" : "Identifier",
"location" : [ 1, 9, 1, 9 ],
"name" : "z"
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 13, 1, 13 ],
"value" : 1
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,4 @@
class Foo(object):
x:int = 1
f = Foo()

@ -0,0 +1,65 @@
{
"kind" : "Program",
"location" : [ 1, 1, 4, 10 ],
"declarations" : [ {
"kind" : "ClassDef",
"location" : [ 1, 1, 2, 14 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 7, 1, 9 ],
"name" : "Foo"
},
"superClass" : {
"kind" : "Identifier",
"location" : [ 1, 11, 1, 16 ],
"name" : "object"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 2, 5, 2, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 2, 5, 2, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 5 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 7, 2, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 13, 2, 13 ],
"value" : 1
}
} ]
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 4, 1, 4, 9 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 4, 1, 4, 1 ],
"name" : "f"
} ],
"value" : {
"kind" : "CallExpr",
"location" : [ 4, 5, 4, 9 ],
"function" : {
"kind" : "Identifier",
"location" : [ 4, 5, 4, 7 ],
"name" : "Foo"
},
"args" : [ ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,5 @@
class Foo(object):
x:int = 1
f = Foo()
print(f.x)

@ -0,0 +1,91 @@
{
"kind" : "Program",
"location" : [ 1, 1, 5, 11 ],
"declarations" : [ {
"kind" : "ClassDef",
"location" : [ 1, 1, 2, 14 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 7, 1, 9 ],
"name" : "Foo"
},
"superClass" : {
"kind" : "Identifier",
"location" : [ 1, 11, 1, 16 ],
"name" : "object"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 2, 5, 2, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 2, 5, 2, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 5 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 7, 2, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 13, 2, 13 ],
"value" : 1
}
} ]
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 4, 1, 4, 9 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 4, 1, 4, 1 ],
"name" : "f"
} ],
"value" : {
"kind" : "CallExpr",
"location" : [ 4, 5, 4, 9 ],
"function" : {
"kind" : "Identifier",
"location" : [ 4, 5, 4, 7 ],
"name" : "Foo"
},
"args" : [ ]
}
}, {
"kind" : "ExprStmt",
"location" : [ 5, 1, 5, 10 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 5, 1, 5, 10 ],
"function" : {
"kind" : "Identifier",
"location" : [ 5, 1, 5, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "MemberExpr",
"location" : [ 5, 7, 5, 9 ],
"object" : {
"kind" : "Identifier",
"location" : [ 5, 7, 5, 7 ],
"name" : "f"
},
"member" : {
"kind" : "Identifier",
"location" : [ 5, 9, 5, 9 ],
"name" : "x"
}
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,5 @@
class Foo(object):
x:int = 1
f = Foo()
f.x = 2

@ -0,0 +1,87 @@
{
"kind" : "Program",
"location" : [ 1, 1, 5, 8 ],
"declarations" : [ {
"kind" : "ClassDef",
"location" : [ 1, 1, 2, 14 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 7, 1, 9 ],
"name" : "Foo"
},
"superClass" : {
"kind" : "Identifier",
"location" : [ 1, 11, 1, 16 ],
"name" : "object"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 2, 5, 2, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 2, 5, 2, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 5 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 7, 2, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 13, 2, 13 ],
"value" : 1
}
} ]
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 4, 1, 4, 9 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 4, 1, 4, 1 ],
"name" : "f"
} ],
"value" : {
"kind" : "CallExpr",
"location" : [ 4, 5, 4, 9 ],
"function" : {
"kind" : "Identifier",
"location" : [ 4, 5, 4, 7 ],
"name" : "Foo"
},
"args" : [ ]
}
}, {
"kind" : "AssignStmt",
"location" : [ 5, 1, 5, 7 ],
"targets" : [ {
"kind" : "MemberExpr",
"location" : [ 5, 1, 5, 3 ],
"object" : {
"kind" : "Identifier",
"location" : [ 5, 1, 5, 1 ],
"name" : "f"
},
"member" : {
"kind" : "Identifier",
"location" : [ 5, 3, 5, 3 ],
"name" : "x"
}
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 5, 7, 5, 7 ],
"value" : 2
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,8 @@
class Foo(object):
x:int = 0
def __init__(self:"Foo", x:int):
self.x = x
f = Foo(1)
print(f.x)

@ -0,0 +1,159 @@
{
"kind" : "Program",
"location" : [ 1, 1, 8, 11 ],
"declarations" : [ {
"kind" : "ClassDef",
"location" : [ 1, 1, 7, 0 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 7, 1, 9 ],
"name" : "Foo"
},
"superClass" : {
"kind" : "Identifier",
"location" : [ 1, 11, 1, 16 ],
"name" : "object"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 2, 5, 2, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 2, 5, 2, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 5 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 7, 2, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 13, 2, 13 ],
"value" : 0
}
}, {
"kind" : "FuncDef",
"location" : [ 4, 5, 5, 19 ],
"name" : {
"kind" : "Identifier",
"location" : [ 4, 9, 4, 16 ],
"name" : "__init__"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 4, 18, 4, 27 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 4, 18, 4, 21 ],
"name" : "self"
},
"type" : {
"kind" : "ClassType",
"location" : [ 4, 23, 4, 27 ],
"className" : "Foo"
}
}, {
"kind" : "TypedVar",
"location" : [ 4, 30, 4, 34 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 4, 30, 4, 30 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 4, 32, 4, 34 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 4, 36, 4, 36 ],
"className" : "<None>"
},
"declarations" : [ ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 5, 9, 5, 18 ],
"targets" : [ {
"kind" : "MemberExpr",
"location" : [ 5, 9, 5, 14 ],
"object" : {
"kind" : "Identifier",
"location" : [ 5, 9, 5, 12 ],
"name" : "self"
},
"member" : {
"kind" : "Identifier",
"location" : [ 5, 14, 5, 14 ],
"name" : "x"
}
} ],
"value" : {
"kind" : "Identifier",
"location" : [ 5, 18, 5, 18 ],
"name" : "x"
}
} ]
} ]
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 7, 1, 7, 10 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 7, 1, 7, 1 ],
"name" : "f"
} ],
"value" : {
"kind" : "CallExpr",
"location" : [ 7, 5, 7, 10 ],
"function" : {
"kind" : "Identifier",
"location" : [ 7, 5, 7, 7 ],
"name" : "Foo"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 7, 9, 7, 9 ],
"value" : 1
} ]
}
}, {
"kind" : "ExprStmt",
"location" : [ 8, 1, 8, 10 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 8, 1, 8, 10 ],
"function" : {
"kind" : "Identifier",
"location" : [ 8, 1, 8, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "MemberExpr",
"location" : [ 8, 7, 8, 9 ],
"object" : {
"kind" : "Identifier",
"location" : [ 8, 7, 8, 7 ],
"name" : "f"
},
"member" : {
"kind" : "Identifier",
"location" : [ 8, 9, 8, 9 ],
"name" : "x"
}
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,9 @@
class Foo(object):
x:int = 0
def set(self:"Foo", x:int) -> object:
self.x = x
f = Foo()
f.set(1)
print(f.x)

@ -0,0 +1,181 @@
{
"kind" : "Program",
"location" : [ 1, 1, 9, 11 ],
"declarations" : [ {
"kind" : "ClassDef",
"location" : [ 1, 1, 7, 0 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 7, 1, 9 ],
"name" : "Foo"
},
"superClass" : {
"kind" : "Identifier",
"location" : [ 1, 11, 1, 16 ],
"name" : "object"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 2, 5, 2, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 2, 5, 2, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 5 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 7, 2, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 13, 2, 13 ],
"value" : 0
}
}, {
"kind" : "FuncDef",
"location" : [ 4, 5, 5, 19 ],
"name" : {
"kind" : "Identifier",
"location" : [ 4, 9, 4, 11 ],
"name" : "set"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 4, 13, 4, 22 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 4, 13, 4, 16 ],
"name" : "self"
},
"type" : {
"kind" : "ClassType",
"location" : [ 4, 18, 4, 22 ],
"className" : "Foo"
}
}, {
"kind" : "TypedVar",
"location" : [ 4, 25, 4, 29 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 4, 25, 4, 25 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 4, 27, 4, 29 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 4, 35, 4, 40 ],
"className" : "object"
},
"declarations" : [ ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 5, 9, 5, 18 ],
"targets" : [ {
"kind" : "MemberExpr",
"location" : [ 5, 9, 5, 14 ],
"object" : {
"kind" : "Identifier",
"location" : [ 5, 9, 5, 12 ],
"name" : "self"
},
"member" : {
"kind" : "Identifier",
"location" : [ 5, 14, 5, 14 ],
"name" : "x"
}
} ],
"value" : {
"kind" : "Identifier",
"location" : [ 5, 18, 5, 18 ],
"name" : "x"
}
} ]
} ]
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 7, 1, 7, 9 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 7, 1, 7, 1 ],
"name" : "f"
} ],
"value" : {
"kind" : "CallExpr",
"location" : [ 7, 5, 7, 9 ],
"function" : {
"kind" : "Identifier",
"location" : [ 7, 5, 7, 7 ],
"name" : "Foo"
},
"args" : [ ]
}
}, {
"kind" : "ExprStmt",
"location" : [ 8, 1, 8, 8 ],
"expr" : {
"kind" : "MethodCallExpr",
"location" : [ 8, 1, 8, 8 ],
"method" : {
"kind" : "MemberExpr",
"location" : [ 8, 1, 8, 5 ],
"object" : {
"kind" : "Identifier",
"location" : [ 8, 1, 8, 1 ],
"name" : "f"
},
"member" : {
"kind" : "Identifier",
"location" : [ 8, 3, 8, 5 ],
"name" : "set"
}
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 8, 7, 8, 7 ],
"value" : 1
} ]
}
}, {
"kind" : "ExprStmt",
"location" : [ 9, 1, 9, 10 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 9, 1, 9, 10 ],
"function" : {
"kind" : "Identifier",
"location" : [ 9, 1, 9, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "MemberExpr",
"location" : [ 9, 7, 9, 9 ],
"object" : {
"kind" : "Identifier",
"location" : [ 9, 7, 9, 7 ],
"name" : "f"
},
"member" : {
"kind" : "Identifier",
"location" : [ 9, 9, 9, 9 ],
"name" : "x"
}
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,38 @@
count:int = 0
def foo(s: str) -> int:
return len(s)
class bar(object):
p: bool = True
def baz(self:"bar", xx: [int]) -> str:
global count
x:int = 0
y:int = 1
def qux(y: int) -> object:
nonlocal x
if x > y:
x = -1
for x in xx:
self.p = x == 2
qux(0) # Yay! ChocoPy
count = count + 1
while x <= 0:
if self.p:
xx[0] = xx[1]
self.p = not self.p
x = x + 1
elif foo("Long"[0]) == 1:
return self is None
return "Nope"
print(bar().baz([1,2]))

@ -0,0 +1,613 @@
{
"kind" : "Program",
"location" : [ 1, 1, 36, 24 ],
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 1, 1, 1, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 1, 1, 1, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 5 ],
"name" : "count"
},
"type" : {
"kind" : "ClassType",
"location" : [ 1, 7, 1, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 13, 1, 13 ],
"value" : 0
}
}, {
"kind" : "FuncDef",
"location" : [ 3, 1, 4, 18 ],
"name" : {
"kind" : "Identifier",
"location" : [ 3, 5, 3, 7 ],
"name" : "foo"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 3, 9, 3, 14 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 3, 9, 3, 9 ],
"name" : "s"
},
"type" : {
"kind" : "ClassType",
"location" : [ 3, 12, 3, 14 ],
"className" : "str"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 3, 20, 3, 22 ],
"className" : "int"
},
"declarations" : [ ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 4, 5, 4, 17 ],
"value" : {
"kind" : "CallExpr",
"location" : [ 4, 12, 4, 17 ],
"function" : {
"kind" : "Identifier",
"location" : [ 4, 12, 4, 14 ],
"name" : "len"
},
"args" : [ {
"kind" : "Identifier",
"location" : [ 4, 16, 4, 16 ],
"name" : "s"
} ]
}
} ]
}, {
"kind" : "ClassDef",
"location" : [ 6, 1, 36, 0 ],
"name" : {
"kind" : "Identifier",
"location" : [ 6, 7, 6, 9 ],
"name" : "bar"
},
"superClass" : {
"kind" : "Identifier",
"location" : [ 6, 11, 6, 16 ],
"name" : "object"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 7, 5, 7, 18 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 7, 5, 7, 11 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 7, 5, 7, 5 ],
"name" : "p"
},
"type" : {
"kind" : "ClassType",
"location" : [ 7, 8, 7, 11 ],
"className" : "bool"
}
},
"value" : {
"kind" : "BooleanLiteral",
"location" : [ 7, 15, 7, 18 ],
"value" : true
}
}, {
"kind" : "FuncDef",
"location" : [ 9, 5, 34, 22 ],
"name" : {
"kind" : "Identifier",
"location" : [ 9, 9, 9, 11 ],
"name" : "baz"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 9, 13, 9, 22 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 9, 13, 9, 16 ],
"name" : "self"
},
"type" : {
"kind" : "ClassType",
"location" : [ 9, 18, 9, 22 ],
"className" : "bar"
}
}, {
"kind" : "TypedVar",
"location" : [ 9, 25, 9, 33 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 9, 25, 9, 26 ],
"name" : "xx"
},
"type" : {
"kind" : "ListType",
"location" : [ 9, 29, 9, 33 ],
"elementType" : {
"kind" : "ClassType",
"location" : [ 9, 30, 9, 32 ],
"className" : "int"
}
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 9, 39, 9, 41 ],
"className" : "str"
},
"declarations" : [ {
"kind" : "GlobalDecl",
"location" : [ 10, 9, 10, 20 ],
"variable" : {
"kind" : "Identifier",
"location" : [ 10, 16, 10, 20 ],
"name" : "count"
}
}, {
"kind" : "VarDef",
"location" : [ 11, 9, 11, 17 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 11, 9, 11, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 11, 9, 11, 9 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 11, 11, 11, 13 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 11, 17, 11, 17 ],
"value" : 0
}
}, {
"kind" : "VarDef",
"location" : [ 12, 9, 12, 17 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 12, 9, 12, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 12, 9, 12, 9 ],
"name" : "y"
},
"type" : {
"kind" : "ClassType",
"location" : [ 12, 11, 12, 13 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 12, 17, 12, 17 ],
"value" : 1
}
}, {
"kind" : "FuncDef",
"location" : [ 14, 9, 19, 8 ],
"name" : {
"kind" : "Identifier",
"location" : [ 14, 13, 14, 15 ],
"name" : "qux"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 14, 17, 14, 22 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 14, 17, 14, 17 ],
"name" : "y"
},
"type" : {
"kind" : "ClassType",
"location" : [ 14, 20, 14, 22 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 14, 28, 14, 33 ],
"className" : "object"
},
"declarations" : [ {
"kind" : "NonLocalDecl",
"location" : [ 15, 13, 15, 22 ],
"variable" : {
"kind" : "Identifier",
"location" : [ 15, 22, 15, 22 ],
"name" : "x"
}
} ],
"statements" : [ {
"kind" : "IfStmt",
"location" : [ 16, 13, 19, 8 ],
"condition" : {
"kind" : "BinaryExpr",
"location" : [ 16, 16, 16, 20 ],
"left" : {
"kind" : "Identifier",
"location" : [ 16, 16, 16, 16 ],
"name" : "x"
},
"operator" : ">",
"right" : {
"kind" : "Identifier",
"location" : [ 16, 20, 16, 20 ],
"name" : "y"
}
},
"thenBody" : [ {
"kind" : "AssignStmt",
"location" : [ 17, 17, 17, 22 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 17, 17, 17, 17 ],
"name" : "x"
} ],
"value" : {
"kind" : "UnaryExpr",
"location" : [ 17, 21, 17, 22 ],
"operator" : "-",
"operand" : {
"kind" : "IntegerLiteral",
"location" : [ 17, 22, 17, 22 ],
"value" : 1
}
}
} ],
"elseBody" : [ ]
} ]
} ],
"statements" : [ {
"kind" : "ForStmt",
"location" : [ 19, 9, 22, 8 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 19, 13, 19, 13 ],
"name" : "x"
},
"iterable" : {
"kind" : "Identifier",
"location" : [ 19, 18, 19, 19 ],
"name" : "xx"
},
"body" : [ {
"kind" : "AssignStmt",
"location" : [ 20, 13, 20, 27 ],
"targets" : [ {
"kind" : "MemberExpr",
"location" : [ 20, 13, 20, 18 ],
"object" : {
"kind" : "Identifier",
"location" : [ 20, 13, 20, 16 ],
"name" : "self"
},
"member" : {
"kind" : "Identifier",
"location" : [ 20, 18, 20, 18 ],
"name" : "p"
}
} ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 20, 22, 20, 27 ],
"left" : {
"kind" : "Identifier",
"location" : [ 20, 22, 20, 22 ],
"name" : "x"
},
"operator" : "==",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 20, 27, 20, 27 ],
"value" : 2
}
}
} ]
}, {
"kind" : "ExprStmt",
"location" : [ 22, 9, 22, 14 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 22, 9, 22, 14 ],
"function" : {
"kind" : "Identifier",
"location" : [ 22, 9, 22, 11 ],
"name" : "qux"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 22, 13, 22, 13 ],
"value" : 0
} ]
}
}, {
"kind" : "AssignStmt",
"location" : [ 24, 9, 24, 25 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 24, 9, 24, 13 ],
"name" : "count"
} ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 24, 17, 24, 25 ],
"left" : {
"kind" : "Identifier",
"location" : [ 24, 17, 24, 21 ],
"name" : "count"
},
"operator" : "+",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 24, 25, 24, 25 ],
"value" : 1
}
}
}, {
"kind" : "WhileStmt",
"location" : [ 26, 9, 34, 8 ],
"condition" : {
"kind" : "BinaryExpr",
"location" : [ 26, 15, 26, 20 ],
"left" : {
"kind" : "Identifier",
"location" : [ 26, 15, 26, 15 ],
"name" : "x"
},
"operator" : "<=",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 26, 20, 26, 20 ],
"value" : 0
}
},
"body" : [ {
"kind" : "IfStmt",
"location" : [ 27, 13, 34, 8 ],
"condition" : {
"kind" : "MemberExpr",
"location" : [ 27, 16, 27, 21 ],
"object" : {
"kind" : "Identifier",
"location" : [ 27, 16, 27, 19 ],
"name" : "self"
},
"member" : {
"kind" : "Identifier",
"location" : [ 27, 21, 27, 21 ],
"name" : "p"
}
},
"thenBody" : [ {
"kind" : "AssignStmt",
"location" : [ 28, 17, 28, 29 ],
"targets" : [ {
"kind" : "IndexExpr",
"location" : [ 28, 17, 28, 21 ],
"list" : {
"kind" : "Identifier",
"location" : [ 28, 17, 28, 18 ],
"name" : "xx"
},
"index" : {
"kind" : "IntegerLiteral",
"location" : [ 28, 20, 28, 20 ],
"value" : 0
}
} ],
"value" : {
"kind" : "IndexExpr",
"location" : [ 28, 25, 28, 29 ],
"list" : {
"kind" : "Identifier",
"location" : [ 28, 25, 28, 26 ],
"name" : "xx"
},
"index" : {
"kind" : "IntegerLiteral",
"location" : [ 28, 28, 28, 28 ],
"value" : 1
}
}
}, {
"kind" : "AssignStmt",
"location" : [ 29, 17, 29, 35 ],
"targets" : [ {
"kind" : "MemberExpr",
"location" : [ 29, 17, 29, 22 ],
"object" : {
"kind" : "Identifier",
"location" : [ 29, 17, 29, 20 ],
"name" : "self"
},
"member" : {
"kind" : "Identifier",
"location" : [ 29, 22, 29, 22 ],
"name" : "p"
}
} ],
"value" : {
"kind" : "UnaryExpr",
"location" : [ 29, 26, 29, 35 ],
"operator" : "not",
"operand" : {
"kind" : "MemberExpr",
"location" : [ 29, 30, 29, 35 ],
"object" : {
"kind" : "Identifier",
"location" : [ 29, 30, 29, 33 ],
"name" : "self"
},
"member" : {
"kind" : "Identifier",
"location" : [ 29, 35, 29, 35 ],
"name" : "p"
}
}
}
}, {
"kind" : "AssignStmt",
"location" : [ 30, 17, 30, 25 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 30, 17, 30, 17 ],
"name" : "x"
} ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 30, 21, 30, 25 ],
"left" : {
"kind" : "Identifier",
"location" : [ 30, 21, 30, 21 ],
"name" : "x"
},
"operator" : "+",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 30, 25, 30, 25 ],
"value" : 1
}
}
} ],
"elseBody" : [ {
"kind" : "IfStmt",
"location" : [ 31, 13, 34, 8 ],
"condition" : {
"kind" : "BinaryExpr",
"location" : [ 31, 18, 31, 36 ],
"left" : {
"kind" : "CallExpr",
"location" : [ 31, 18, 31, 31 ],
"function" : {
"kind" : "Identifier",
"location" : [ 31, 18, 31, 20 ],
"name" : "foo"
},
"args" : [ {
"kind" : "IndexExpr",
"location" : [ 31, 22, 31, 30 ],
"list" : {
"kind" : "StringLiteral",
"location" : [ 31, 22, 31, 27 ],
"value" : "Long"
},
"index" : {
"kind" : "IntegerLiteral",
"location" : [ 31, 29, 31, 29 ],
"value" : 0
}
} ]
},
"operator" : "==",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 31, 36, 31, 36 ],
"value" : 1
}
},
"thenBody" : [ {
"kind" : "ReturnStmt",
"location" : [ 32, 17, 32, 35 ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 32, 24, 32, 35 ],
"left" : {
"kind" : "Identifier",
"location" : [ 32, 24, 32, 27 ],
"name" : "self"
},
"operator" : "is",
"right" : {
"kind" : "NoneLiteral",
"location" : [ 32, 32, 32, 35 ]
}
}
} ],
"elseBody" : [ ]
} ]
} ]
}, {
"kind" : "ReturnStmt",
"location" : [ 34, 9, 34, 21 ],
"value" : {
"kind" : "StringLiteral",
"location" : [ 34, 16, 34, 21 ],
"value" : "Nope"
}
} ]
} ]
} ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 36, 1, 36, 23 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 36, 1, 36, 23 ],
"function" : {
"kind" : "Identifier",
"location" : [ 36, 1, 36, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "MethodCallExpr",
"location" : [ 36, 7, 36, 22 ],
"method" : {
"kind" : "MemberExpr",
"location" : [ 36, 7, 36, 15 ],
"object" : {
"kind" : "CallExpr",
"location" : [ 36, 7, 36, 11 ],
"function" : {
"kind" : "Identifier",
"location" : [ 36, 7, 36, 9 ],
"name" : "bar"
},
"args" : [ ]
},
"member" : {
"kind" : "Identifier",
"location" : [ 36, 13, 36, 15 ],
"name" : "baz"
}
},
"args" : [ {
"kind" : "ListExpr",
"location" : [ 36, 17, 36, 21 ],
"elements" : [ {
"kind" : "IntegerLiteral",
"location" : [ 36, 18, 36, 18 ],
"value" : 1
}, {
"kind" : "IntegerLiteral",
"location" : [ 36, 20, 36, 20 ],
"value" : 2
} ]
} ]
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,4 @@
def foo() -> int:
return 1
foo()

@ -0,0 +1,48 @@
{
"kind" : "Program",
"location" : [ 1, 1, 4, 6 ],
"declarations" : [ {
"kind" : "FuncDef",
"location" : [ 1, 1, 2, 13 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 5, 1, 7 ],
"name" : "foo"
},
"params" : [ ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 1, 14, 1, 16 ],
"className" : "int"
},
"declarations" : [ ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 2, 5, 2, 12 ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 2, 12, 2, 12 ],
"value" : 1
}
} ]
} ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 4, 1, 4, 5 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 4, 1, 4, 5 ],
"function" : {
"kind" : "Identifier",
"location" : [ 4, 1, 4, 3 ],
"name" : "foo"
},
"args" : [ ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,4 @@
def foo(x:int, y:int) -> bool:
return x > y
foo(1,2)

@ -0,0 +1,92 @@
{
"kind" : "Program",
"location" : [ 1, 1, 4, 9 ],
"declarations" : [ {
"kind" : "FuncDef",
"location" : [ 1, 1, 2, 17 ],
"name" : {
"kind" : "Identifier",
"location" : [ 1, 5, 1, 7 ],
"name" : "foo"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 1, 9, 1, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 1, 9, 1, 9 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 1, 11, 1, 13 ],
"className" : "int"
}
}, {
"kind" : "TypedVar",
"location" : [ 1, 16, 1, 20 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 1, 16, 1, 16 ],
"name" : "y"
},
"type" : {
"kind" : "ClassType",
"location" : [ 1, 18, 1, 20 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 1, 26, 1, 29 ],
"className" : "bool"
},
"declarations" : [ ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 2, 5, 2, 16 ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 2, 12, 2, 16 ],
"left" : {
"kind" : "Identifier",
"location" : [ 2, 12, 2, 12 ],
"name" : "x"
},
"operator" : ">",
"right" : {
"kind" : "Identifier",
"location" : [ 2, 16, 2, 16 ],
"name" : "y"
}
}
} ]
} ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 4, 1, 4, 8 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 4, 1, 4, 8 ],
"function" : {
"kind" : "Identifier",
"location" : [ 4, 1, 4, 3 ],
"name" : "foo"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 4, 5, 4, 5 ],
"value" : 1
}, {
"kind" : "IntegerLiteral",
"location" : [ 4, 7, 4, 7 ],
"value" : 2
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,7 @@
z:int = 0
def foo(x:int) -> bool:
global z
return x > z
foo(1)

@ -0,0 +1,105 @@
{
"kind" : "Program",
"location" : [ 1, 1, 7, 7 ],
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 1, 1, 1, 9 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 1, 1, 1, 5 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 1 ],
"name" : "z"
},
"type" : {
"kind" : "ClassType",
"location" : [ 1, 3, 1, 5 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 9, 1, 9 ],
"value" : 0
}
}, {
"kind" : "FuncDef",
"location" : [ 3, 1, 5, 17 ],
"name" : {
"kind" : "Identifier",
"location" : [ 3, 5, 3, 7 ],
"name" : "foo"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 3, 9, 3, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 3, 9, 3, 9 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 3, 11, 3, 13 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 3, 19, 3, 22 ],
"className" : "bool"
},
"declarations" : [ {
"kind" : "GlobalDecl",
"location" : [ 4, 5, 4, 12 ],
"variable" : {
"kind" : "Identifier",
"location" : [ 4, 12, 4, 12 ],
"name" : "z"
}
} ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 5, 5, 5, 16 ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 5, 12, 5, 16 ],
"left" : {
"kind" : "Identifier",
"location" : [ 5, 12, 5, 12 ],
"name" : "x"
},
"operator" : ">",
"right" : {
"kind" : "Identifier",
"location" : [ 5, 16, 5, 16 ],
"name" : "z"
}
}
} ]
} ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 7, 1, 7, 6 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 7, 1, 7, 6 ],
"function" : {
"kind" : "Identifier",
"location" : [ 7, 1, 7, 3 ],
"name" : "foo"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 7, 5, 7, 5 ],
"value" : 1
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,10 @@
def foo(x:int) -> bool:
a:int = 0
b:int = 1
def bar(y: int) -> int:
a:int = 2
return y
return bar(x) > a
foo(1)

@ -0,0 +1,187 @@
{
"kind" : "Program",
"location" : [ 2, 1, 10, 7 ],
"declarations" : [ {
"kind" : "FuncDef",
"location" : [ 2, 1, 8, 22 ],
"name" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 7 ],
"name" : "foo"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 2, 9, 2, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 9, 2, 9 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 11, 2, 13 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 2, 19, 2, 22 ],
"className" : "bool"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 3, 5, 3, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 3, 5, 3, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 3, 5, 3, 5 ],
"name" : "a"
},
"type" : {
"kind" : "ClassType",
"location" : [ 3, 7, 3, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 13, 3, 13 ],
"value" : 0
}
}, {
"kind" : "VarDef",
"location" : [ 4, 5, 4, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 4, 5, 4, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 4, 5, 4, 5 ],
"name" : "b"
},
"type" : {
"kind" : "ClassType",
"location" : [ 4, 7, 4, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 4, 13, 4, 13 ],
"value" : 1
}
}, {
"kind" : "FuncDef",
"location" : [ 5, 5, 7, 17 ],
"name" : {
"kind" : "Identifier",
"location" : [ 5, 9, 5, 11 ],
"name" : "bar"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 5, 13, 5, 18 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 5, 13, 5, 13 ],
"name" : "y"
},
"type" : {
"kind" : "ClassType",
"location" : [ 5, 16, 5, 18 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 5, 24, 5, 26 ],
"className" : "int"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 6, 9, 6, 17 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 6, 9, 6, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 6, 9, 6, 9 ],
"name" : "a"
},
"type" : {
"kind" : "ClassType",
"location" : [ 6, 11, 6, 13 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 6, 17, 6, 17 ],
"value" : 2
}
} ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 7, 9, 7, 16 ],
"value" : {
"kind" : "Identifier",
"location" : [ 7, 16, 7, 16 ],
"name" : "y"
}
} ]
} ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 8, 5, 8, 21 ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 8, 12, 8, 21 ],
"left" : {
"kind" : "CallExpr",
"location" : [ 8, 12, 8, 17 ],
"function" : {
"kind" : "Identifier",
"location" : [ 8, 12, 8, 14 ],
"name" : "bar"
},
"args" : [ {
"kind" : "Identifier",
"location" : [ 8, 16, 8, 16 ],
"name" : "x"
} ]
},
"operator" : ">",
"right" : {
"kind" : "Identifier",
"location" : [ 8, 21, 8, 21 ],
"name" : "a"
}
}
} ]
} ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 10, 1, 10, 6 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 10, 1, 10, 6 ],
"function" : {
"kind" : "Identifier",
"location" : [ 10, 1, 10, 3 ],
"name" : "foo"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 10, 5, 10, 5 ],
"value" : 1
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,11 @@
def foo(x:int) -> bool:
a:int = 0
b:int = 1
def bar(y: int) -> int:
nonlocal a
a = 2
return y
return bar(x) > a
foo(1)

@ -0,0 +1,186 @@
{
"kind" : "Program",
"location" : [ 2, 1, 11, 7 ],
"declarations" : [ {
"kind" : "FuncDef",
"location" : [ 2, 1, 9, 22 ],
"name" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 7 ],
"name" : "foo"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 2, 9, 2, 13 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 9, 2, 9 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 2, 11, 2, 13 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 2, 19, 2, 22 ],
"className" : "bool"
},
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 3, 5, 3, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 3, 5, 3, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 3, 5, 3, 5 ],
"name" : "a"
},
"type" : {
"kind" : "ClassType",
"location" : [ 3, 7, 3, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 13, 3, 13 ],
"value" : 0
}
}, {
"kind" : "VarDef",
"location" : [ 4, 5, 4, 13 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 4, 5, 4, 9 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 4, 5, 4, 5 ],
"name" : "b"
},
"type" : {
"kind" : "ClassType",
"location" : [ 4, 7, 4, 9 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 4, 13, 4, 13 ],
"value" : 1
}
}, {
"kind" : "FuncDef",
"location" : [ 5, 5, 8, 17 ],
"name" : {
"kind" : "Identifier",
"location" : [ 5, 9, 5, 11 ],
"name" : "bar"
},
"params" : [ {
"kind" : "TypedVar",
"location" : [ 5, 13, 5, 18 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 5, 13, 5, 13 ],
"name" : "y"
},
"type" : {
"kind" : "ClassType",
"location" : [ 5, 16, 5, 18 ],
"className" : "int"
}
} ],
"returnType" : {
"kind" : "ClassType",
"location" : [ 5, 24, 5, 26 ],
"className" : "int"
},
"declarations" : [ {
"kind" : "NonLocalDecl",
"location" : [ 6, 9, 6, 18 ],
"variable" : {
"kind" : "Identifier",
"location" : [ 6, 18, 6, 18 ],
"name" : "a"
}
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 7, 9, 7, 13 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 7, 9, 7, 9 ],
"name" : "a"
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 7, 13, 7, 13 ],
"value" : 2
}
}, {
"kind" : "ReturnStmt",
"location" : [ 8, 9, 8, 16 ],
"value" : {
"kind" : "Identifier",
"location" : [ 8, 16, 8, 16 ],
"name" : "y"
}
} ]
} ],
"statements" : [ {
"kind" : "ReturnStmt",
"location" : [ 9, 5, 9, 21 ],
"value" : {
"kind" : "BinaryExpr",
"location" : [ 9, 12, 9, 21 ],
"left" : {
"kind" : "CallExpr",
"location" : [ 9, 12, 9, 17 ],
"function" : {
"kind" : "Identifier",
"location" : [ 9, 12, 9, 14 ],
"name" : "bar"
},
"args" : [ {
"kind" : "Identifier",
"location" : [ 9, 16, 9, 16 ],
"name" : "x"
} ]
},
"operator" : ">",
"right" : {
"kind" : "Identifier",
"location" : [ 9, 21, 9, 21 ],
"name" : "a"
}
}
} ]
} ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 11, 1, 11, 6 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 11, 1, 11, 6 ],
"function" : {
"kind" : "Identifier",
"location" : [ 11, 1, 11, 3 ],
"name" : "foo"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 11, 5, 11, 5 ],
"value" : 1
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,43 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 18 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 17 ],
"expr" : {
"kind" : "IfExpr",
"location" : [ 1, 1, 1, 17 ],
"condition" : {
"kind" : "BinaryExpr",
"location" : [ 1, 6, 1, 10 ],
"left" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 6, 1, 6 ],
"value" : 1
},
"operator" : ">",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 10, 1, 10 ],
"value" : 2
}
},
"thenExpr" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 1, 1, 1 ],
"value" : 3
},
"elseExpr" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 17, 1, 17 ],
"value" : 4
}
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1 @@
3 if 1 > 2 else 4 if 1 < 0 else 5

@ -0,0 +1,67 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 34 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 33 ],
"expr" : {
"kind" : "IfExpr",
"location" : [ 1, 1, 1, 33 ],
"condition" : {
"kind" : "BinaryExpr",
"location" : [ 1, 6, 1, 10 ],
"left" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 6, 1, 6 ],
"value" : 1
},
"operator" : ">",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 10, 1, 10 ],
"value" : 2
}
},
"thenExpr" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 1, 1, 1 ],
"value" : 3
},
"elseExpr" : {
"kind" : "IfExpr",
"location" : [ 1, 17, 1, 33 ],
"condition" : {
"kind" : "BinaryExpr",
"location" : [ 1, 22, 1, 26 ],
"left" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 22, 1, 22 ],
"value" : 1
},
"operator" : "<",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 26, 1, 26 ],
"value" : 0
}
},
"thenExpr" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 17, 1, 17 ],
"value" : 4
},
"elseExpr" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 33, 1, 33 ],
"value" : 5
}
}
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,47 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 12 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 11 ],
"expr" : {
"kind" : "BinaryExpr",
"location" : [ 1, 1, 1, 11 ],
"left" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 1 ],
"name" : "a"
},
"operator" : "+",
"right" : {
"kind" : "IndexExpr",
"location" : [ 1, 5, 1, 11 ],
"list" : {
"kind" : "IndexExpr",
"location" : [ 1, 5, 1, 8 ],
"list" : {
"kind" : "Identifier",
"location" : [ 1, 5, 1, 5 ],
"name" : "b"
},
"index" : {
"kind" : "Identifier",
"location" : [ 1, 7, 1, 7 ],
"name" : "i"
}
},
"index" : {
"kind" : "Identifier",
"location" : [ 1, 10, 1, 10 ],
"name" : "j"
}
}
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,39 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 10 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 9 ],
"expr" : {
"kind" : "BinaryExpr",
"location" : [ 1, 1, 1, 9 ],
"left" : {
"kind" : "BinaryExpr",
"location" : [ 1, 1, 1, 5 ],
"left" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 1, 1, 1 ],
"value" : 1
},
"operator" : "+",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 5, 1, 5 ],
"value" : 2
}
},
"operator" : "+",
"right" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 9, 1, 9 ],
"value" : 3
}
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,24 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 3 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 2 ],
"expr" : {
"kind" : "UnaryExpr",
"location" : [ 1, 1, 1, 2 ],
"operator" : "-",
"operand" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 2, 1, 2 ],
"value" : 1
}
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,5 @@
x:int = 1
x = 2
print(x)

@ -0,0 +1,63 @@
{
"kind" : "Program",
"location" : [ 1, 1, 5, 9 ],
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 1, 1, 1, 9 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 1, 1, 1, 5 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 1 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 1, 3, 1, 5 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 9, 1, 9 ],
"value" : 1
}
} ],
"statements" : [ {
"kind" : "AssignStmt",
"location" : [ 3, 1, 3, 5 ],
"targets" : [ {
"kind" : "Identifier",
"location" : [ 3, 1, 3, 1 ],
"name" : "x"
} ],
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 5, 3, 5 ],
"value" : 2
}
}, {
"kind" : "ExprStmt",
"location" : [ 5, 1, 5, 8 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 5, 1, 5, 8 ],
"function" : {
"kind" : "Identifier",
"location" : [ 5, 1, 5, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "Identifier",
"location" : [ 5, 7, 5, 7 ],
"name" : "x"
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,7 @@
True
False
1
None
"This is a string"
[1, 2, 3]

@ -0,0 +1,70 @@
{
"kind" : "Program",
"location" : [ 1, 1, 6, 10 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 4 ],
"expr" : {
"kind" : "BooleanLiteral",
"location" : [ 1, 1, 1, 4 ],
"value" : true
}
}, {
"kind" : "ExprStmt",
"location" : [ 2, 1, 2, 5 ],
"expr" : {
"kind" : "BooleanLiteral",
"location" : [ 2, 1, 2, 5 ],
"value" : false
}
}, {
"kind" : "ExprStmt",
"location" : [ 3, 1, 3, 1 ],
"expr" : {
"kind" : "IntegerLiteral",
"location" : [ 3, 1, 3, 1 ],
"value" : 1
}
}, {
"kind" : "ExprStmt",
"location" : [ 4, 1, 4, 4 ],
"expr" : {
"kind" : "NoneLiteral",
"location" : [ 4, 1, 4, 4 ]
}
}, {
"kind" : "ExprStmt",
"location" : [ 5, 1, 5, 18 ],
"expr" : {
"kind" : "StringLiteral",
"location" : [ 5, 1, 5, 18 ],
"value" : "This is a string"
}
}, {
"kind" : "ExprStmt",
"location" : [ 6, 1, 6, 9 ],
"expr" : {
"kind" : "ListExpr",
"location" : [ 6, 1, 6, 9 ],
"elements" : [ {
"kind" : "IntegerLiteral",
"location" : [ 6, 2, 6, 2 ],
"value" : 1
}, {
"kind" : "IntegerLiteral",
"location" : [ 6, 5, 6, 5 ],
"value" : 2
}, {
"kind" : "IntegerLiteral",
"location" : [ 6, 8, 6, 8 ],
"value" : 3
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,28 @@
{
"kind" : "Program",
"location" : [ 1, 1, 1, 9 ],
"declarations" : [ ],
"statements" : [ {
"kind" : "ExprStmt",
"location" : [ 1, 1, 1, 8 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 1, 1, 1, 8 ],
"function" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 5 ],
"name" : "print"
},
"args" : [ {
"kind" : "IntegerLiteral",
"location" : [ 1, 7, 1, 7 ],
"value" : 1
} ]
}
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

@ -0,0 +1,4 @@
x:int = 0
for x in [1, 2, 3]:
print(x)

@ -0,0 +1,76 @@
{
"kind" : "Program",
"location" : [ 1, 1, 5, 1 ],
"declarations" : [ {
"kind" : "VarDef",
"location" : [ 1, 1, 1, 9 ],
"var" : {
"kind" : "TypedVar",
"location" : [ 1, 1, 1, 5 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 1, 1, 1, 1 ],
"name" : "x"
},
"type" : {
"kind" : "ClassType",
"location" : [ 1, 3, 1, 5 ],
"className" : "int"
}
},
"value" : {
"kind" : "IntegerLiteral",
"location" : [ 1, 9, 1, 9 ],
"value" : 0
}
} ],
"statements" : [ {
"kind" : "ForStmt",
"location" : [ 2, 1, 5, 1 ],
"identifier" : {
"kind" : "Identifier",
"location" : [ 2, 5, 2, 5 ],
"name" : "x"
},
"iterable" : {
"kind" : "ListExpr",
"location" : [ 2, 10, 2, 18 ],
"elements" : [ {
"kind" : "IntegerLiteral",
"location" : [ 2, 11, 2, 11 ],
"value" : 1
}, {
"kind" : "IntegerLiteral",
"location" : [ 2, 14, 2, 14 ],
"value" : 2
}, {
"kind" : "IntegerLiteral",
"location" : [ 2, 17, 2, 17 ],
"value" : 3
} ]
},
"body" : [ {
"kind" : "ExprStmt",
"location" : [ 3, 5, 3, 12 ],
"expr" : {
"kind" : "CallExpr",
"location" : [ 3, 5, 3, 12 ],
"function" : {
"kind" : "Identifier",
"location" : [ 3, 5, 3, 9 ],
"name" : "print"
},
"args" : [ {
"kind" : "Identifier",
"location" : [ 3, 11, 3, 11 ],
"name" : "x"
} ]
}
} ]
} ],
"errors" : {
"errors" : [ ],
"kind" : "Errors",
"location" : [ 0, 0, 0, 0 ]
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save