171 lines
4.2 KiB
JavaScript
171 lines
4.2 KiB
JavaScript
|
var assignments = require('./assignments')
|
||
|
var ignoredKeywords = require('./ignored')
|
||
|
|
||
|
module.exports = assigns
|
||
|
|
||
|
// Here be dragons. Apologies in advance for the hairy code!
|
||
|
function assigns(tokens) {
|
||
|
var idx = 0
|
||
|
|
||
|
// Determine if a value has been assigned, e.g.
|
||
|
// x = 1.0;
|
||
|
// float x = 1.0;
|
||
|
for (var i = 0; i < tokens.length; i++) {
|
||
|
var token = tokens[i]
|
||
|
var type = token.type
|
||
|
|
||
|
token.assignment = false
|
||
|
token.declaration = false
|
||
|
if (type !== 'ident' && type !== 'builtin') continue
|
||
|
idx = i + 1
|
||
|
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].type !== 'operator') continue
|
||
|
if (!assignments[tokens[idx].data]) continue
|
||
|
token.assignment = true
|
||
|
}
|
||
|
|
||
|
// Determine if a value is being defined, e.g.
|
||
|
// float x;
|
||
|
// float x, y, z;
|
||
|
// float x, y = vec3(sin(1.0 + 3.0)), z;
|
||
|
// float[3][2] x, y = vec3(sin(1.0 + 3.0)), z;
|
||
|
// float[][2] x, y = vec3(sin(1.0 + 3.0)), z;
|
||
|
// float x[2], y = vec3(sin(1.0 + 3.0)), z[4];
|
||
|
// float x(float y, float z) {};
|
||
|
// float x(float y[2], Thing[3] z) {};
|
||
|
// Thing x[2], y = Another(sin(1.0 + 3.0)), z[4];
|
||
|
for (var i = 0; i < tokens.length; i++) {
|
||
|
var datatype = tokens[i]
|
||
|
var type = datatype.type
|
||
|
var data = datatype.data
|
||
|
|
||
|
datatype.declaration = false
|
||
|
|
||
|
if (type === 'keyword') {
|
||
|
if (ignoredKeywords[data]) continue
|
||
|
} else
|
||
|
if (type !== 'ident') continue
|
||
|
|
||
|
idx = i + 1
|
||
|
|
||
|
skipArrayDimensions()
|
||
|
if (tokens[idx].type !== 'ident') continue
|
||
|
tokens[idx++].declaration = true
|
||
|
skipArrayDimensions()
|
||
|
|
||
|
// Function arguments/parameters
|
||
|
if (tokens[idx].data === '(') {
|
||
|
idx++
|
||
|
|
||
|
skipWhitespace(+1)
|
||
|
while (tokens[idx] && tokens[idx].data !== ')') {
|
||
|
if (tokens[idx].type !== 'keyword' && tokens[idx].type !== 'ident') break
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].type !== 'ident') continue
|
||
|
tokens[idx++].declaration = true
|
||
|
skipWhitespace(+1)
|
||
|
skipArrayDimensions()
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].data !== ',') continue
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
}
|
||
|
|
||
|
i = idx
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// Declaration Lists
|
||
|
while (tokens[idx] && tokens[idx].data !== ';') {
|
||
|
if (tokens[idx].data === ',') {
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].declaration = tokens[idx].type === 'ident') idx++
|
||
|
} else {
|
||
|
skipWhitespace(+1)
|
||
|
skipParens()
|
||
|
skipWhitespace(+1)
|
||
|
idx++
|
||
|
}
|
||
|
}
|
||
|
|
||
|
i = idx
|
||
|
}
|
||
|
|
||
|
// Handle struct declarations:
|
||
|
// struct declaration {
|
||
|
// float x, y, z;
|
||
|
// Other w;
|
||
|
// } declaration;
|
||
|
for (var i = 0; i < tokens.length; i++) {
|
||
|
var token = tokens[i]
|
||
|
if (token.type !== 'keyword') continue
|
||
|
if (token.data !== 'struct') continue
|
||
|
idx = i + 1
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].type !== 'ident') continue
|
||
|
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx++].data !== '{') continue
|
||
|
skipWhitespace(+1)
|
||
|
|
||
|
while (tokens[idx].type === 'ident' || tokens[idx].type === 'keyword') {
|
||
|
do {
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
tokens[idx].structMember = true
|
||
|
tokens[idx].declaration = false
|
||
|
idx++
|
||
|
skipArrayDimensions()
|
||
|
} while (tokens[idx].data === ',')
|
||
|
|
||
|
if (tokens[idx].data === ';') idx++
|
||
|
skipWhitespace()
|
||
|
}
|
||
|
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].type !== 'ident') continue
|
||
|
tokens[idx].declaration = true
|
||
|
skipWhitespace(+1)
|
||
|
|
||
|
while (tokens[++idx].data === ',') {
|
||
|
skipWhitespace(+1)
|
||
|
idx++
|
||
|
skipWhitespace(+1)
|
||
|
if (tokens[idx].type === 'ident') tokens[idx].declaration = true
|
||
|
skipWhitespace(+1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return tokens
|
||
|
|
||
|
function skipWhitespace(n) {
|
||
|
while (tokens[idx] && tokens[idx].type === 'whitespace') idx++
|
||
|
}
|
||
|
|
||
|
function skipArrayDimensions() {
|
||
|
while (tokens[idx] && (
|
||
|
tokens[idx].type === 'integer'
|
||
|
|| tokens[idx].data === '['
|
||
|
|| tokens[idx].data === ']'
|
||
|
|| tokens[idx].type === 'whitespace'
|
||
|
)) idx++
|
||
|
}
|
||
|
|
||
|
function skipParens() {
|
||
|
if (!tokens[idx]) return
|
||
|
if (tokens[idx].data !== '(') return
|
||
|
var depth = 0
|
||
|
var a = idx
|
||
|
do {
|
||
|
if (tokens[idx].data === ';') break
|
||
|
if (tokens[idx].data === '(') depth++
|
||
|
if (tokens[idx].data === ')') depth--
|
||
|
} while(depth && tokens[++idx])
|
||
|
}
|
||
|
}
|