Binden binaere Operatoren zu schwach?
-
Kellerautomat schrieb:
Ich bastle gerade an einer eigenen Programmiersprache und habe ueber Operator-Prioritaeten nachgedacht.
Machs wie in C, das kennen die Leute wenigstens, auch wenn es teilweise keinen Sinn zu machen scheint. BTW, gibts bei dir einen Potenzoperator? Die sind besonders lustig ...
-
Nein, es gibt derzeit keinen Potenzoperator. Die Begruendung "Machs so, wie Leute das kennen" hat fuer mich keinen Wert. Meine Sprache soll dem Benutzer moeglichst viel Tipparbeit und Verkrampfungen auf der Tastatur ersparen. Da ist mir ziemlich egal, was andere Programmierer (inkl. mir) gewohnt sind.

Z.B. habe ich die bedeutung von &&/& und ||/| vertauscht, weil man die logischen Operatoren viel oefters braucht. Scopes werden anstatt {} durch [] markiert, weil das auf meiner englischen Tastatur kein Shift braucht. Semikolone sind grundsaetzlich unnoetig, \n ist auch ein gueltiger Terminator. if, while und for brauchen keine (). Statt [] verwende ich fuer Arrays @.
Das mag alles nur nach Kleinigkeiten klingen, aber in Summe betrachtet kommt da schon was zusammen.

-
Ja, eine Sprache mit der keiner arbeiten will kommt da zusammen
Das ist wie ein von QWERTY abweichendes Tastaturlayout. Vielleicht ergonomischer, aber irgendwie sinnlos.MfG SideWinder
-
Ach was, so schlimm sieht das gar nicht aus. Herrlich sinnloses Codebeispiel:
# comment int@ f = { 2, 4, 6 } main(string@ args) => void [ foo f = new foo f.qux f.baz ] type foo [ alias bar = foo baz() => int [ <-- ::f return 0 ] qux(int x) => void [ if x % 42 == 0 <-- true for int i = 0; i < 2; ++i <-- i if .b [ <-- x --> .b ? .i : x .b = x -> bool ] else <-- "huehuehue" ] bool b, c int i ]
-
Ich geh mal davon aus, du machst das nur als Lexer/Parser-Übung

Ansonsten sieht deine Sprache nämlich genau wie jede andere C-basierte Sprache aus, dürfte keine zusätzlichen interessanten Features haben und verwendet zur allgemeinen Verwirrung andere Symbole als gewohnt
Also bitte nicht produktiv einsetzen *g*
BTW: "=> void" spart jetzt aber nicht gerade Schreibarbeit.
MfG SideWinder
-
Kellerautomat schrieb:
Kommt das nur mir falsch vor?
Nope. Das sollte jedem komisch vorkommen

Der Grund warum es so ist wie es ist, ist folgender:
In C gabs ursprünglich && und || garnicht - da hat man & und | verwendet. Deshalb musste ein if(a<b | b<c) korrekt funktionieren. Etwas später kamen dann aber && und || dazu, um short circuit zu erlauben. Aus Kompatibilitätsgründen hat man aber die Precedence von | und & nicht mehr angefasst.
-
SideWinder schrieb:
Ich geh mal davon aus, du machst das nur als Lexer/Parser-Übung

Jop. Allerdings habe ich auch vor, das ganze lauffaehig zu bekommen. Der Lexer ist beretis fertig. Ich verpasse nur gerade der Grammatik den letzten Schliff, danach kommt der Parser.

SideWinder schrieb:
Ansonsten sieht deine Sprache nämlich genau wie jede andere C-basierte Sprache aus
Die Aehnlichkeit ist durchaus vorhanden, ja. Aber warum auch nicht, hat sich schliesslich bewaehrt.
SideWinder schrieb:
dürfte keine zusätzlichen interessanten Features haben
Dem muss ich widersprechen. Mag sein, dass ich damit keine grossen Innovationen bringen, oder gar neue Programmierparadigmen. Aber ich versuche Dinge, die mir in C++ besonders auf den Keks gehen, loszuwerden. Eins davon ist das staendige kennzeichnen von globalen Variablen und Membern. Auf globals greift man bei mir mit :: zu, auf Member mit .

SideWinder schrieb:
und verwendet zur allgemeinen Verwirrung andere Symbole als gewohnt

Ich wuerde sagen, das ist Gewoehnungssache.

SideWinder schrieb:
BTW: "=> void" spart jetzt aber nicht gerade Schreibarbeit.
Ich nenne es "trailing return types done right".

-
Ah, als Übung natürlich sehr interessant. Wie hast du Lexer/Parser geschrieben? Verwendest du flex/bison oder baust du alles von Hand?
Übersetzerbau war eine meiner Lieblings-LVAs im Bachelorstudium. Allerdings mussten wir die attributierte Grammatik mit "ox", einem undokumentierten Uralt-Tool erledigen, pfui.
Lustigster Teil bleibt dann aber imho die Code-Optimierung, auch wenn man da gnadenlos jedem anderen Compiler unterlegen ist und man besser nur ein Language-Frontend für gcc bastelt.
MfG SideWinder
-
Kellerautomat schrieb:
Ich wuerde sagen, das ist Gewoehnungssache.

Warum verwendet man denn andere Zeichen für Dinge, die man von überall her kennt und nichtmal eine andere Bedeutung haben?
-
Cyres schrieb:
Kellerautomat schrieb:
Ich wuerde sagen, das ist Gewoehnungssache.

Warum verwendet man denn andere Zeichen für Dinge, die man von überall her kennt und nichtmal eine andere Bedeutung haben?
Hat er doch schon weiter oben beantwortet.
MfG SideWinder
-
Alles von Hand gebaut mit der C++-Standardlib only.

-
SideWinder schrieb:
Lustigster Teil bleibt dann aber imho die Code-Optimierung, auch wenn man da gnadenlos jedem anderen Compiler unterlegen ist und man besser nur ein Language-Frontend für gcc bastelt.
Wenn das so nah an C++ ist, wie das hier klingt, kann er auch "einfach" nach C++ übersetzen. Je nachdem, wie nah seine Sprache ist, geht das relativ einfach.
mir ist allerdings nicht klar, was die "-->" und "<--" machen sollen.
-
otze schrieb:
mir ist allerdings nicht klar, was die "-->" und "<--" machen sollen.
Eingabe und Ausgabe

-
Shade Of Mine schrieb:
In C gabs ursprünglich && und || garnicht - da hat man & und | verwendet.
Quelle dafür:
http://www.lysator.liu.se/c/dmr-on-or.html
-
Falls es jemanden interessiert: Ich habe gerade die Grammatik fertiggestellt. Zur Info: a % b bedeutet "beliebig viele Vorkommen von a, getrennt durch b".
module = definition* definition = type-definition | function-definition | variable-definition | alias-definition | terminator type-definition = 'type' identifier '[' (function-definition | variable-definition | alias-definition | terminator)* ']' function-definition = identifier [':' parameter % ','] '=>' type compound-statement variable-definition = type identifier '=' expression terminator alias-definition = 'alias' identifier = type terminator identifier = {a-zA-Z_}{a-zA-Z_0-9} && !built-in-type parameter = type identifier type = type-name [type-modifier] type-name = built-in-type | identifier ['.' identifier] built-in-type = void | bool | char | int | float type-modifier = '@' terminator = '\n' | ';' statement = selection-statement | iteration-statement | jump-statement | io-statement | definition-statement | expression-statement | compound-statement selection-statement = if-statement if-statement = 'if' expression terminator statement ['else' statement] iteration-statement = for-statement | while-statement for-statement = 'for' variable-definition | terminator expression-statement [expression] terminator statement while-statement = 'while' expression terminator statement expression-statement = [expression] terminator jump-statement = break-statement | continue-statement | return-statement break-statement = 'break' terminator continue-statement = 'continue' terminator return-statement = 'return' expression terminator io-statement = input-statement | output-statement input-statement = '-->' expression terminator output-statement = '<--' expression terminator definition-statement = variable-definition | alias-definition compound-statement = '[' statement* ']' expression = comma-expression ['$' expression] comma-expression = assignment-expression [',' expression] assignment-expression = cast-expression [assignment-operator assignment-expression] cast-expression = conditional-expression ['->' type] conditional-expression = logical-or-expression ['?' expression ':' assignment-expression] logical-or-expression = logical-xor-expression ['|' logical-or-expression] logical-xor-expression = logical-and-expression ['^' logical-xor-expression] logical-and-expression = equality-expression ['&' logical-and-expression] equality-expression = relational-expression ['==' | '!=' equality-expression] relational-expression = bitwise-or-expression ['<' | '>' | '<=' | '>=' relational-expression] bitwise-or-expression = bitwise-xor-expression ['||' bitwise-or-expression] bitwise-xor-expression = bitwise-and-expression ['^^' bitwise-xor-expression] bitwise-and-expression = shift-expression ['&&' bitwise-and-expression] shift-expression = additive-expression ['<<' | '>>' shift-expression] additive-expression = multiplicative-expression ['+' | '-' additive-expression] multiplicative-expression = infix-function-call ['*' | '/' | '%' multiplicative-expression] infix-function-call = prefix-expression [':' accessor ':' prefix-expression] prefix-expression = prefix-operator* postfix-expression postfix-expression = primary-expression [postfix-operator-sequence] primary-expression = '(' expression ')' | literal | accessor | 'this' | function-call | new-expression function-call = accessor primary-expression* new-expression = 'new' type accessor = global-accessor | member-accessor | object-accessor global-accessor = '::' object-accessor member-accessor = '.' object-accessor object-accessor = identifier [member-accessor] prefix-operator = '+' | '-' | '++' | '--' | '!' | '~' postfix-operator-sequence = ['@' primary-expression] postfix-operator* postfix-operator = '++' | '--' assignment-operator = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '&=' | '|=' | '^=' | '&&=' | '||=' | '^^=' literal = bool-literal | int-literal | float-literal | char-literal | string-literal | array-literal bool-literal = 'true' | 'false' int-literal = digit+ float-literal = digit+ '.' digit+ char-literal = '\'' character '\'' string-literal = '"' character* '"' array-literal = '{' expression % ',' '}'Ist ganz schoen viel geworden.

-
hast du die Grammatik auf irgendwelche Eigenschaften getuned? also LL(k), LR(k)...
-
Nope. Ich weiss zwar, dass es verschiedene Kategorien von Grammatiken gibt, die verschwieden schwer zu parsen sind, aber so aufs erste fange ich auch mit den Wikipedia-Artikeln darueber wenig an. So genau habe ich mich mit dem Thema nicht auseinandergesetzt. Aber der Parser ist in meinem Kopf schon im Prinzip fertig.
