Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d00548f
wip: initial simple ref check
joe-p Apr 9, 2025
61033f5
wip: ts-based ref checker
joe-p Apr 9, 2025
9374727
wip: fix eslint
joe-p Apr 9, 2025
cb725c9
wip: fix ref test
joe-p Apr 9, 2025
079357d
wip: rm extra clone on Address
joe-p Apr 11, 2025
78ca0c0
wip: fix assignment check, function check, and tests
joe-p Apr 11, 2025
a8ba20c
wip: MutableRefInVariableDeclaration
joe-p Apr 11, 2025
f7e0521
wip: MutableRefInVariableDeclarationWithDynamicIndex
joe-p Apr 12, 2025
36e447d
wip: fix some of the false positives
joe-p Apr 12, 2025
31f4c7f
wip: treat function args like other references
joe-p Apr 12, 2025
6154aab
wip: simplify access check
joe-p Apr 12, 2025
3a9d9a2
wip: rm variable decl check because it's supported by TEALScript
joe-p Apr 12, 2025
b05c37d
wip: ref checker 2
joe-p Apr 12, 2025
06b2117
wip: array in obj tests
joe-p Apr 12, 2025
185d26b
wip: obj tests
joe-p Apr 12, 2025
32a8d77
wip: compile all
joe-p Apr 12, 2025
d1ded98
wip: check array functions (push)
joe-p Apr 12, 2025
a8ee311
wip: improve error message
joe-p Apr 12, 2025
5c5d525
wip: even better error messages
joe-p Apr 13, 2025
910eb9a
wip: allow clone in push
joe-p Apr 13, 2025
fe4acb8
wip: add suggestion to push error msg
joe-p Apr 13, 2025
ba94c15
wip: ArrayAssignmentWithAliasMutation
joe-p Apr 13, 2025
9a7408e
wip: obj assignment test
joe-p Apr 13, 2025
c04c392
wip: obj ref within mutation
joe-p Apr 13, 2025
84ebb49
wip: uncomment bug line
joe-p Apr 13, 2025
2c58e78
wip: swap error message order
joe-p May 7, 2025
b7b9688
wip: improve error formatting
joe-p May 17, 2025
f6f80a6
wip: move comments above to avoid output in errors
joe-p May 17, 2025
e2081b9
wip: add chalk
joe-p May 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions examples/reti/artifacts/ValidatorRegistry.approval.teal
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ getPools:

*if0_end:
// examples/reti/validatorRegistry.algo.ts:325
// retData.push(poolSet[i])
// retData.push(clone(poolSet[i]))
frame_dig 0 // retData: PoolInfo[]
frame_dig 1 // poolSet: (uint64,uint16,uint64)[24]
frame_dig 2 // i: uint64
Expand Down Expand Up @@ -933,7 +933,7 @@ getStakedPoolsForAccount:

// *if4_consequent
// examples/reti/validatorRegistry.algo.ts:390
// retData.push(poolSet[i])
// retData.push(clone(poolSet[i]))
frame_dig 0 // retData: ValidatorPoolKey[]
frame_dig 1 // poolSet: (uint64,uint64,uint64)[6]
frame_dig 2 // i: uint64
Expand Down Expand Up @@ -2376,7 +2376,7 @@ addStake:

*if10_end:
// examples/reti/validatorRegistry.algo.ts:696
// this.updateStakerPoolSet(staker, poolKey)
// this.updateStakerPoolSet(staker, clone(poolKey))
frame_dig 3 // findRet: ((uint64,uint64,uint64),bool,bool)
store 255 // full array
load 255 // full array
Expand All @@ -2387,7 +2387,7 @@ addStake:
// examples/reti/validatorRegistry.algo.ts:699
// this.callPoolAddStake(
// stakedAmountPayment,
// poolKey,
// clone(poolKey),
// mbrAmtLeftBehind,
// isNewStakerToValidator,
// isNewStakerToProtocol
Expand Down
2 changes: 1 addition & 1 deletion examples/reti/artifacts/ValidatorRegistry.arc32.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/reti/artifacts/ValidatorRegistry.arc56.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions examples/reti/validatorRegistry.algo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export class ValidatorRegistry extends Contract {
// reached end of list... we don't replace values here because pools can't be removed
break;
}
retData.push(poolSet[i]);
retData.push(clone(poolSet[i]));
}
return retData;
}
Expand Down Expand Up @@ -387,7 +387,7 @@ export class ValidatorRegistry extends Contract {
const poolSet = clone(this.stakerPoolSet(staker).value);
for (let i = 0; i < poolSet.length; i += 1) {
if (poolSet[i].id !== 0) {
retData.push(poolSet[i]);
retData.push(clone(poolSet[i]));
}
}
return retData;
Expand Down Expand Up @@ -693,12 +693,12 @@ export class ValidatorRegistry extends Contract {
}

// Update StakerPoolList for this found pool (new or existing)
this.updateStakerPoolSet(staker, poolKey);
this.updateStakerPoolSet(staker, clone(poolKey));
// Send the callers algo amount (- mbrAmtLeftBehind) to the specified staking pool, and it then updates
// the staker data.
this.callPoolAddStake(
stakedAmountPayment,
poolKey,
clone(poolKey),
mbrAmtLeftBehind,
isNewStakerToValidator,
isNewStakerToProtocol
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"@microsoft/tsdoc": "^0.14.2",
"@playwright/test": "^1.40.1",
"argparse": "^2.0.1",
"chalk": "^5.4.1",
"dotenv": "^16.3.1",
"glob": "^10.3.10",
"hi-base32": "^0.5.1",
Expand Down
1 change: 1 addition & 0 deletions scripts/compile_all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const examplesArtifacts = {
async function main() {
const files = globSync(path.join(__dirname, '../**/*.algo.ts'));
files.forEach((file) => {
if (file.includes('reference_errors')) return;
if (file.includes('compile_errors')) return;
const isExample = file.includes('examples/');
const project = isExample ? EXAMPLES_PROJECT : TESTS_PROJECT;
Expand Down
47 changes: 8 additions & 39 deletions src/lib/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import langspec from '../static/langspec.json';
import { VERSION } from '../version';
import { optimizeTeal } from './optimize';
import { type ARC56Contract, type StructField } from '../types/arc56.d';
import { checkRefs } from './ref_checker2';
import { getExpressionChain, ExpressionChainNode } from './utils';

const MULTI_OUTPUT_TYPES = ['split uint128', 'divmodw output', 'vrf return values', 'ecdsa pubkey'];

type ExpressionChainNode = ts.ElementAccessExpression | ts.PropertyAccessExpression | ts.CallExpression;

type OnComplete = 'NoOp' | 'OptIn' | 'CloseOut' | 'ClearState' | 'UpdateApplication' | 'DeleteApplication';
const ON_COMPLETES: ['NoOp', 'OptIn', 'CloseOut', 'ClearState', 'UpdateApplication', 'DeleteApplication'] = [
'NoOp',
Expand Down Expand Up @@ -2038,6 +2038,7 @@ export default class Compiler {
if (this.lastType.kind !== 'dynamicArray') throw new Error('Can only push to dynamic array');
if (!this.isDynamicArrayOfStaticType(this.lastType))
throw new Error('Cannot push to dynamic array of dynamic types');

this.processNode(node.getArguments()[0]);
this.checkEncoding(node.getArguments()[0], this.lastType);
this.pushVoid(node, 'concat');
Expand Down Expand Up @@ -2837,6 +2838,10 @@ export default class Compiler {

// Go over all the files we are importing and check for number keywords
[sourceFile, ...importedFiles].forEach((f) => {
if (f === undefined) return;

checkRefs(f, path.relative(this.cwd, f.getFilePath()));

f?.getStatements().forEach((s) => {
const numberKeywords = s.getDescendantsOfKind(ts.SyntaxKind.NumberKeyword);

Expand Down Expand Up @@ -3696,42 +3701,6 @@ export default class Compiler {
this.processArrayElements(node.getElements(), node);
}

/**
*
* @param node The top level node to process
* @param chain The existing expression chain to add to
* @returns The base expression and reversed expression chain `this.txn.sender` ->
* `{ chain: [this.txn, this.txn.sender], base: [this] }`
*/
private getExpressionChain(
node: ExpressionChainNode,
chain: ExpressionChainNode[] = []
): { chain: ExpressionChainNode[]; base: ts.Node } {
chain.push(node);

/**
* The expression on the given node
* `this.txn.sender` -> `this.txn`
*/
let expr: ts.Expression = node.getExpression();

/* this.txn.applicationArgs! -> this.txn.applicationArgs */
if (expr.isKind(ts.SyntaxKind.NonNullExpression)) {
expr = expr.getExpression();
}

if (
expr.isKind(ts.SyntaxKind.ElementAccessExpression) ||
expr.isKind(ts.SyntaxKind.PropertyAccessExpression) ||
expr.isKind(ts.SyntaxKind.CallExpression)
) {
return this.getExpressionChain(expr, chain);
}

chain.reverse();
return { base: expr, chain };
}

private getAccessChain(node: ts.ElementAccessExpression, chain: ts.ElementAccessExpression[] = []) {
chain.push(node);

Expand Down Expand Up @@ -6316,7 +6285,7 @@ export default class Compiler {
}
}

const { base, chain } = this.getExpressionChain(node);
const { base, chain } = getExpressionChain(node);

if (base.isKind(ts.SyntaxKind.ParenthesizedExpression)) {
if (!base.getExpression().isKind(ts.SyntaxKind.BinaryExpression))
Expand Down
Loading
Loading