Skip to content

Commit 05cf007

Browse files
committed
Merge pawtograder
2 parents 44216e7 + 9a69d6b commit 05cf007

File tree

23 files changed

+8163
-0
lines changed

23 files changed

+8163
-0
lines changed

pawtograder/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist/
2+
# instead of jarr
3+
*.cjs

pawtograder/.swcrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "https://swc.rs/schema.json",
3+
"jsc": {
4+
"parser": {
5+
"syntax": "typescript"
6+
},
7+
"target": "esnext"
8+
}
9+
}

pawtograder/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# pyret-autograder-pawtograder
2+
3+
An adaptor between the [Pawtograder](https://github.com/pawtograder) platform
4+
and the [pyret-autograder](https://github.com/neu-cs2000/pyret-autograder).

pawtograder/flake.lock

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pawtograder/flake.nix

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
inputs = {
3+
nixpkgs.url = "github:NixOS/nixpkgs/release-25.05";
4+
systems.url = "github:nix-systems/default";
5+
treefmt-nix.url = "github:numtide/treefmt-nix";
6+
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
7+
};
8+
9+
outputs =
10+
{
11+
nixpkgs,
12+
systems,
13+
treefmt-nix,
14+
...
15+
}:
16+
let
17+
eachSystem = f: nixpkgs.lib.genAttrs (import systems) (s: f (import nixpkgs { system = s; }));
18+
treefmtEval = eachSystem (pkgs: treefmt-nix.lib.evalModule pkgs ./nix/treefmt.nix);
19+
in
20+
{
21+
formatter = eachSystem (pkgs: treefmtEval.${pkgs.system}.config.build.wrapper);
22+
23+
devShells = eachSystem (pkgs: {
24+
default = pkgs.mkShell {
25+
packages = with pkgs; [
26+
nodejs_24
27+
gnumake
28+
] ++ lib.optionals stdenv.isDarwin [ git ];
29+
shellHook = ''
30+
export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath [ pkgs.libuuid ]}:''$LD_LIBRARY_PATH"
31+
'';
32+
};
33+
});
34+
};
35+
}

pawtograder/lib/schema.ts

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
Copyright (C) 2025 ironmoon <[email protected]>
3+
4+
This file is part of pyret-autograder-pawtograder.
5+
6+
pyret-autograder-pawtograder is free software: you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public License as
8+
published by the Free Software Foundation, either version 3 of the License,
9+
or (at your option) any later version.
10+
11+
pyret-autograder-pawtograder is distributed in the hope that it will be
12+
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
14+
General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public License
17+
with pyret-autograder-pawtograder. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
import { z } from "zod";
21+
22+
// ensure that consumers of the library use the same version of zod
23+
export { z };
24+
25+
export const Spec = z.strictObject({
26+
solution_dir: z.string(),
27+
submission_dir: z.string(),
28+
get config() {
29+
return Config;
30+
},
31+
});
32+
33+
export type Spec = z.infer<typeof Spec>;
34+
35+
// NOTE: intentionally allows extra keys at the top level pawtograder.yml
36+
export const Config = z.object({
37+
grader: z.literal("pyret"),
38+
/**
39+
* The default entry point to the student's program, relative to
40+
* {@link Spec.submission_dir}
41+
*/
42+
default_entry: z.string().optional(),
43+
get graders() {
44+
return z.record(z.string(), Grader).transform(Object.entries);
45+
},
46+
});
47+
48+
export type Config = z.infer<typeof Config>;
49+
50+
const BaseGrader = z.strictObject({
51+
deps: z.string().array().optional(),
52+
/**
53+
* The path of the entry point to the student's program.
54+
*
55+
* Defaults to {@link Spec.config.default_entry}
56+
*/
57+
entry: z.string().optional(),
58+
});
59+
60+
const BaseGuard = BaseGrader;
61+
62+
const BaseScorer = BaseGrader.extend({
63+
points: z.number().nonnegative().optional(),
64+
});
65+
66+
const BaseArtist = BaseGrader.extend({
67+
/** outfile, relative to the artifact directory */
68+
out: z.string()
69+
});
70+
71+
const WellFormedGrader = BaseGuard.extend({
72+
type: z.literal("well-formed"),
73+
});
74+
75+
const FunctionDefinedGrader = BaseGuard.extend({
76+
type: z.literal("function-defined"),
77+
config: z.strictObject({
78+
/** the name of the function to check the existance of */
79+
function: z.string(),
80+
/** the expected parameter arity */
81+
arity: z.int().nonnegative(),
82+
}),
83+
});
84+
85+
const ConstantDefinedGrader = BaseGuard.extend({
86+
type: z.literal("constant-defined"),
87+
config: z.strictObject({
88+
/** the name of the constant to check the existance of */
89+
constant: z.string(),
90+
}),
91+
});
92+
93+
const TestDiversityGrader = BaseGuard.extend({
94+
type: z.literal("test-diversity"),
95+
config: z.strictObject({
96+
/** the function to check the submission's test diversity of */
97+
function: z.string(),
98+
/** the minimum number of inputs that must be provided */
99+
min_in: z.int().nonnegative(),
100+
/** the minimum number of *actual* outputs that must be returned */
101+
min_out: z.int().nonnegative(),
102+
}),
103+
});
104+
105+
const TrainingWheelsGrader = BaseGuard.extend({
106+
type: z.literal("training-wheels"),
107+
config: z.strictObject({
108+
/** whether to only check for mutation at the top level of the program */
109+
top_level_only: z.boolean(),
110+
}),
111+
});
112+
113+
const ExamplarGrader = BaseScorer.extend({
114+
type: z.union([z.literal("wheat"), z.literal("chaff")]),
115+
config: z.strictObject({
116+
/** the path which contains the wheat/chaff implementation */
117+
path: z.string(),
118+
/** the name of the function to use */
119+
function: z.string(),
120+
}),
121+
});
122+
123+
const FunctionalGrader = BaseScorer.extend({
124+
type: z.literal("functional"),
125+
config: z.strictObject({
126+
/** the path which contain the check block */
127+
path: z.string(),
128+
/** the name of the check block to use in the provided path */
129+
check: z.string(),
130+
/** the name of the function being tested (improves errors and grouping) */
131+
function: z.string().optional(),
132+
}),
133+
});
134+
135+
const SelfTestGrader = BaseScorer.extend({
136+
type: z.literal("self-test"),
137+
config: z.strictObject({
138+
/** the name of the function to use */
139+
function: z.string(),
140+
}),
141+
});
142+
143+
const FeedbotGrader = BaseGrader.extend({
144+
type: z.literal("feedbot"),
145+
config: z.strictObject({
146+
function: z.string(),
147+
model: z.string().optional(),
148+
provider: z.string().optional(),
149+
temperature: z.number().min(0).max(1).optional(),
150+
account: z.string().optional(),
151+
max_tokens: z.number().min(1).optional(),
152+
}),
153+
});
154+
155+
const ProgramInspectorGrader = BaseGrader.extend({
156+
type: z.literal("program-inspector"),
157+
});
158+
159+
const StyleGrader = BaseScorer.extend({
160+
type: z.literal("style"),
161+
config: z.strictObject({
162+
/*
163+
penalty: z.number()
164+
*/
165+
})
166+
});
167+
168+
const DocChkGrader = BaseScorer.extend({
169+
type: z.literal("docchk"),
170+
config: z.strictObject({
171+
function: z.string(),
172+
}),
173+
})
174+
175+
const ImageArtifactGrader = BaseArtist.extend({
176+
type: z.literal("image-artifact"),
177+
config: z.strictObject({
178+
generator: z.string(),
179+
name: z.string(),
180+
}),
181+
});
182+
183+
export const Grader = z.discriminatedUnion("type", [
184+
WellFormedGrader,
185+
FunctionDefinedGrader,
186+
ConstantDefinedGrader,
187+
TestDiversityGrader,
188+
TrainingWheelsGrader,
189+
ExamplarGrader,
190+
FunctionalGrader,
191+
SelfTestGrader,
192+
FeedbotGrader,
193+
ProgramInspectorGrader,
194+
StyleGrader,
195+
DocChkGrader,
196+
ImageArtifactGrader,
197+
]);
198+
199+
export type Grader = z.infer<typeof Grader>;

0 commit comments

Comments
 (0)