I’m currently developing my own (sort of) programming language.
It currently looks something like this:
asdf = 2;
print(asdf);
And
print(2);
And surprisingly, it works. (Both output 2
)
However, the problem is I can’t do this:
print(sqrt(25));
I also can’t do this:
asdf = sqrt(25);
print(asdf);
My big problem is I can’t use functions in of arguments and variable declarations.
How would I implement this?
(I will give code for the interpreter if needed)
6
You have to evaluate the inner function first, take its result and feed it into your outer function.
In most interpreters, this is typically done by pushing the outer function (and its parentheses) onto a stack. You then evaluate the inner function, obtain the answer, pop the outer function, hand it the answer from the inner function, and evaluate the outer function.
asdf = sqrt(25);
This part is one of the most useful, as you can rewrite majority of code as assignments of function results to variables.
For example:
print(sqrt(25));
can be rewritten as:
tmp0 = sqrt(25);
print(tmp0);
Using this method you can easily handle even nested calls:
print(sqrt(pow(5, 2));
is rewritten as:
tmp0 = pow(5, 2);
tmp1 = sqrt(pow0);
print(tmp1);
and so on.
I don’t know how you implemented you interpreter, but one of the simplest approaches is to first tokenize your input (i.e. turn a source text into a sequence of lexemes – basic symbols that represent different parts of your language’s grammar) and then traverse that sequence.
Remember that you can perform several passes over the sequence of lexemes, in each pass producing gradually simpler sequences until you have something you can easily work with.
Example:
print(sqrt(25));
may be tokenized into the following sequence:
"print"
"("
"sqrt"
"("
"25"
")"
")"
";"
When traversing the sequence you look for patterns (e.g. identifier "("
) and take actions when you find a match.
For example, matching identifier "("
triggers a nested call in you interpreter to rewrite the sequence if the analyser finds nested calls.
Then, you will rewrite it to a modified sequence that may look like this:
"tmp0"
"="
"sqrt"
"("
"25"
")"
";"
"print"
"("
"tmp0"
")"
";"
To make rewriting easier you can operate on two sequences: a raw input sequence, and a fresh one for rewritten program.
Using this method you rewrite and rewrite until you arrive at something simple enough to execute.
That’s, from a very high level, is basically what happens with most programming languages.
I’d advise you to read up on programming language design, lexers, parsers, and source code analysis.
I’d also suggest you try to write a simple DSL before starting a much more complex task of implementing a general purpose language.
Learning more than one programming language also helps when you want to design your own.
3